aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-12-22 21:20:09 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2021-01-04 13:33:10 +0100
commit2c9d5a47ca33eb69d40bc81a8c93aa97e18cc785 (patch)
tree669fd06c641188e5f410576fe8d3020413d66b64
parentconf: rename migration to migration_windows (diff)
downloadwireguard-windows-2c9d5a47ca33eb69d40bc81a8c93aa97e18cc785.tar.xz
wireguard-windows-2c9d5a47ca33eb69d40bc81a8c93aa97e18cc785.zip
build: update to go 1.16 beta1
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--Makefile3
-rw-r--r--build.bat3
-rw-r--r--go-patches/0001-cmd-link-recognize-arm-header-of-PE-objects.patch32
-rw-r--r--go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch59
-rw-r--r--go-patches/0002-cmd-link-deal-with-ADDR32NB-relocations-the-same-way.patch31
-rw-r--r--go-patches/0002-cmd-link-handle-grouped-resource-sections.patch (renamed from go-patches/0005-cmd-link-handle-grouped-resource-sections.patch)150
-rw-r--r--go-patches/0003-cmd-link-ignore-SEH-marking-on-PE-objects.patch47
-rw-r--r--go-patches/0004-cmd-link-do-not-mark-resource-section-as-writable.patch30
-rw-r--r--go-patches/0006-Revert-release-branch.go1.15-runtime-detect-services.patch135
-rw-r--r--go-patches/0007-runtime-do-not-explicitly-exit-on-ctrl-handler.patch49
-rw-r--r--go-patches/0008-runtime-allow-callback-functions-with-up-to-8-argume.patch60
-rw-r--r--go-patches/0009-runtime-use-CreateWaitableTimerEx-to-implement-uslee.patch419
-rw-r--r--go-patches/0010-runtime-allow-for-usleep2HighRes-to-run-without-TLS-.patch91
-rw-r--r--go-patches/0011-cmd-link-windows-arm-is-all-pie-so-mark-it-as-such.patch44
-rw-r--r--go-patches/0012-runtime-adjust-address-calculation-in-identifying-ab.patch44
-rw-r--r--go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch1275
-rw-r--r--go-patches/0014-runtime-make-write-into-function-pointer.patch32
17 files changed, 147 insertions, 2357 deletions
diff --git a/Makefile b/Makefile
index de17c973..74db1df1 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ define download =
if ! mv $$@.unverified $$@; then rm -f $$@.unverified; exit 1; fi
endef
-$(eval $(call download,go.tar.gz,https://golang.org/dl/go1.15.6.linux-amd64.tar.gz,3918e6cc85e7eaaa6f859f1bdbaac772e7a825b0eb423c63d3ae68b21f84b844))
+$(eval $(call download,go.tar.gz,https://golang.org/dl/go1.16beta1.linux-amd64.tar.gz,3931a0d493d411d6c697df6f15d5292fdd8031fde7014fded399effdad4c12d8))
$(eval $(call download,wintun.zip,https://www.wintun.net/builds/wintun-0.10.zip,45bbe63a7cc60e5b6123b8d06747ba703ab3fd636298a50953db10da1d70f5b6))
.deps/go/prepared: .distfiles/go.tar.gz $(wildcard go-patches/*.patch)
@@ -34,7 +34,6 @@ $(eval $(call download,wintun.zip,https://www.wintun.net/builds/wintun-0.10.zip,
tar -C .deps -xzf .distfiles/go.tar.gz
chmod -R +w .deps/go
cat $(filter %.patch,$^) | patch -f -N -r- -p1 -d .deps/go
- cd .deps/go/src && GOARCH=amd64 GOOS=linux go build -v -o ../pkg/tool/linux_amd64/compile cmd/compile
cd .deps/go/src && GOARCH=amd64 GOOS=linux go build -v -o ../pkg/tool/linux_amd64/link cmd/link
touch $@
diff --git a/build.bat b/build.bat
index 365a440f..da6ad338 100644
--- a/build.bat
+++ b/build.bat
@@ -13,7 +13,7 @@ if exist .deps\prepared goto :render
rmdir /s /q .deps 2> NUL
mkdir .deps || goto :error
cd .deps || goto :error
- call :download go.zip https://dl.google.com/go/go1.15.6.windows-amd64.zip b7b3808bb072c2bab73175009187fd5a7f20ffe0a31739937003a14c5c4d9006 || goto :error
+ call :download go.zip https://golang.org/dl/go1.16beta1.windows-amd64.zip f06e2d7f300843473527e8fdd2d496aef5ffa6507ade0ac1141934e5c6ca7d63 || goto :error
rem Mirror of https://github.com/mstorsjo/llvm-mingw/releases/download/20201020/llvm-mingw-20201020-msvcrt-x86_64.zip
call :download llvm-mingw-msvcrt.zip https://download.wireguard.com/windows-toolchain/distfiles/llvm-mingw-20201020-msvcrt-x86_64.zip 2e46593245090df96d15e360e092f0b62b97e93866e0162dca7f93b16722b844 || goto :error
rem Mirror of https://imagemagick.org/download/binaries/ImageMagick-7.0.8-42-portable-Q16-x64.zip
@@ -27,7 +27,6 @@ if exist .deps\prepared goto :render
echo [+] Patching go
for %%a in ("..\go-patches\*.patch") do .\patch.exe -f -N -r- -d go -p1 --binary < "%%a" || goto :error
cd go\src || goto :error
- ..\bin\go build -v -o ..\pkg\tool\windows_amd64\compile.exe cmd/compile || goto :error
..\bin\go build -v -o ..\pkg\tool\windows_amd64\link.exe cmd/link || goto :error
cd ..\.. || goto :error
copy /y NUL prepared > NUL || goto :error
diff --git a/go-patches/0001-cmd-link-recognize-arm-header-of-PE-objects.patch b/go-patches/0001-cmd-link-recognize-arm-header-of-PE-objects.patch
deleted file mode 100644
index 19fdd04a..00000000
--- a/go-patches/0001-cmd-link-recognize-arm-header-of-PE-objects.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From fde4a13eb5eba28ac546b10752b38a80f389cc5a Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 8 Nov 2020 02:48:09 +0100
-Subject: [PATCH 01/14] cmd/link: recognize arm header of PE objects
-
-The linker recognizes headers for 386 and amd64 PE objects, but not arm
-objects. This is easily overlooked, since its the same as the 386 header
-value, except the two nibbles of the first word are swapped. This commit
-simply adds the check for this. Without it, .syso objects are rejected,
-which means Windows binaries can't have resources built into them.
-
-Change-Id: I210411d978504c1a9540e23abc5a180e24f159ad
----
- src/cmd/link/internal/ld/lib.go | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
-index 0366bc7a6f..f98668a7dc 100644
---- a/src/cmd/link/internal/ld/lib.go
-+++ b/src/cmd/link/internal/ld/lib.go
-@@ -1893,7 +1893,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
- return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
- }
-
-- if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 {
-+ if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 || c1 == 0xc4 && c2 == 0x01 {
- ldpe := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
- textp, rsrc, err := loadpe.Load(ctxt.loader, ctxt.Arch, ctxt.Syms.IncVersion(), f, pkg, length, pn)
- if err != nil {
---
-2.29.2
-
diff --git a/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch b/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch
new file mode 100644
index 00000000..a22ec91f
--- /dev/null
+++ b/go-patches/0001-runtime-allow-builtin-write-function-to-be-redirecte.patch
@@ -0,0 +1,59 @@
+From 293b84bef3f6656a263248ff00c9d2fb82f4168d Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Thu, 3 Dec 2020 13:29:58 +0100
+Subject: [PATCH 1/2] runtime: allow builtin write function to be redirected
+ with function pointer
+
+The x/sys/windows package currently uses go:linkname for other facilities
+inside of runtime that are not suitable to be exposed as a public API
+due to their dangers but are still necessary for manipulating any
+low-level plumbing that the runtime controls.
+
+Logging, via the built-in println and panic handler, is one such
+low-level plumbing feature. In this case, x/sys/windows/svc needs to be
+able to redirect panics to the Windows event log. Because the event log
+is a complicated interface, this requires a bit more fiddling than the
+simple solution used on Android (baking it into runtime itself), and
+because Windows services are very diverse, the event log might not even
+always be a desirable destination.
+
+This commit accomplishes this by exposing a function pointer called
+"overrideWrite" that low-level runtime packages like x/sys/windows/svc
+can use to redirect output logs toward the event log or otherwise.
+
+It is not safe or acceptable to use as a generic mechanism, and for that
+reason, we wouldn't want to expose this as a real stable API, similar to
+the other instances of go:linkname in x/sys/windows. But for packages
+that must interoperate with low-level Go runtime fundamentals, this is a
+safety hatch for packages that are developed in tandem with the runtime.
+x/sys/windows is one such package.
+
+Fixes #42888.
+
+Change-Id: I77a32ff7e1494324e8cc38e792e007f86d32672d
+---
+ src/runtime/time_nofake.go | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/runtime/time_nofake.go b/src/runtime/time_nofake.go
+index 1912a94e87..0564448b2e 100644
+--- a/src/runtime/time_nofake.go
++++ b/src/runtime/time_nofake.go
+@@ -23,9 +23,14 @@ func walltime() (sec int64, nsec int32) {
+ return walltime1()
+ }
+
++var overrideWrite func(fd uintptr, p unsafe.Pointer, n int32) int32
++
+ // write must be nosplit on Windows (see write1)
+ //
+ //go:nosplit
+ func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
++ if overrideWrite != nil {
++ return overrideWrite(fd, noescape(p), n)
++ }
+ return write1(fd, p, n)
+ }
+--
+2.29.2
+
diff --git a/go-patches/0002-cmd-link-deal-with-ADDR32NB-relocations-the-same-way.patch b/go-patches/0002-cmd-link-deal-with-ADDR32NB-relocations-the-same-way.patch
deleted file mode 100644
index e260ccd8..00000000
--- a/go-patches/0002-cmd-link-deal-with-ADDR32NB-relocations-the-same-way.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From a0a59fc25f4d8aef3c7bce38c84f04c504745f0e Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 8 Nov 2020 03:09:42 +0100
-Subject: [PATCH 02/14] cmd/link: deal with ADDR32NB relocations the same way
- as ADDR32 on arm
-
-As far as I can tell, the addend is the same for both of these, and in
-this context we don't really care about setting or unsetting the thumb
-selection bit, so just treat these the same way.
-
-Change-Id: I3756c027239f77778c32b317733df9ac92272580
----
- src/cmd/link/internal/loadpe/ldpe.go | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
-index cf76741f43..5839a6a5f2 100644
---- a/src/cmd/link/internal/loadpe/ldpe.go
-+++ b/src/cmd/link/internal/loadpe/ldpe.go
-@@ -308,7 +308,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
-
- rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
-
-- case IMAGE_REL_ARM_ADDR32:
-+ case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
- rType = objabi.R_ADDR
-
- rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
---
-2.29.2
-
diff --git a/go-patches/0005-cmd-link-handle-grouped-resource-sections.patch b/go-patches/0002-cmd-link-handle-grouped-resource-sections.patch
index 02af61a2..85fbc3e9 100644
--- a/go-patches/0005-cmd-link-handle-grouped-resource-sections.patch
+++ b/go-patches/0002-cmd-link-handle-grouped-resource-sections.patch
@@ -1,7 +1,7 @@
-From 5d5d74f35dd3375cda8ef2ba8257547aad107ecb Mon Sep 17 00:00:00 2001
+From f7465aae6e0e8bc4c90c3b8386f5a2a574a15de0 Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
Date: Sun, 8 Nov 2020 11:57:42 +0100
-Subject: [PATCH 05/14] cmd/link: handle grouped resource sections
+Subject: [PATCH 2/2] cmd/link: handle grouped resource sections
The Go PE linker does not support enough generalized PE logic to
properly handle .rsrc sections gracefully. Instead a few things are
@@ -26,28 +26,46 @@ sections, just as there isn't generic support already for what resources
require. Instead we augment the resource handling logic to deal with
standard two-section resource objects.
+We also add a test for this, akin to the current test for more vanilla
+binutils resource objects, and make sure that the rsrc tests are always
+performed.
+
+Fixes #42866.
+Fixes #43182.
+
Change-Id: I059450021405cdf2ef1c195ddbab3960764ad711
+Reviewed-on: https://go-review.googlesource.com/c/go/+/268337
+Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
+TryBot-Result: Go Bot <gobot@golang.org>
+Reviewed-by: Cherry Zhang <cherryyz@google.com>
+Trust: Alex Brainman <alex.brainman@gmail.com>
+Trust: Jason A. Donenfeld <Jason@zx2c4.com>
---
- src/cmd/link/internal/ld/lib.go | 2 +-
- src/cmd/link/internal/ld/pe.go | 50 ++++++++++++++--------------
- src/cmd/link/internal/loadpe/ldpe.go | 47 ++++++++++++++------------
- 3 files changed, 52 insertions(+), 47 deletions(-)
+ src/cmd/link/internal/ld/lib.go | 2 +-
+ src/cmd/link/internal/ld/pe.go | 60 ++++++++++--------
+ src/cmd/link/internal/loadpe/ldpe.go | 49 +++++++-------
+ src/cmd/link/link_test.go | 19 ++++++
+ .../link/testdata/testPErsrc-complex/main.go | 43 +++++++++++++
+ .../testdata/testPErsrc-complex/rsrc.syso | Bin 0 -> 352 bytes
+ 6 files changed, 124 insertions(+), 49 deletions(-)
+ create mode 100644 src/cmd/link/testdata/testPErsrc-complex/main.go
+ create mode 100644 src/cmd/link/testdata/testPErsrc-complex/rsrc.syso
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
-index f98668a7dc..f09b5910b9 100644
+index f3c301cc9b..9c2231a34e 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
-@@ -1900,7 +1900,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
+@@ -1808,7 +1808,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
Errorf(nil, "%v", err)
return
}
- if rsrc != 0 {
-+ if rsrc != nil {
++ if len(rsrc) != 0 {
setpersrc(ctxt, rsrc)
}
- ctxt.Textp2 = append(ctxt.Textp2, textp...)
+ ctxt.Textp = append(ctxt.Textp, textp...)
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
-index ec5b6d5f52..29094fe8ed 100644
+index adbf516d5c..5edaf54dd2 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -253,7 +253,7 @@ type Dll struct {
@@ -59,47 +77,44 @@ index ec5b6d5f52..29094fe8ed 100644
PESECTHEADR int32
PEFILEHEADR int32
pe64 int
-@@ -1464,47 +1464,47 @@ func (ctxt *Link) dope() {
+@@ -1508,46 +1508,56 @@ func (ctxt *Link) dope() {
initdynexport(ctxt)
}
-func setpersrc(ctxt *Link, sym loader.Sym) {
- if rsrcsym != 0 {
+func setpersrc(ctxt *Link, syms []loader.Sym) {
-+ if rsrcsyms != nil {
++ if len(rsrcsyms) != 0 {
Errorf(nil, "too many .rsrc sections")
}
-
- rsrcsym = sym
-- ctxt.loader.SetAttrReachable(rsrcsym, true)
+ rsrcsyms = syms
-+ for i := range rsrcsyms {
-+ ctxt.loader.SetAttrReachable(rsrcsyms[i], true)
-+ }
}
func addpersrc(ctxt *Link) {
- if rsrcsym == 0 {
-+ if rsrcsyms == nil {
++ if len(rsrcsyms) == 0 {
return
}
-- rsrc := ctxt.loader.Syms[rsrcsym]
-- data := rsrc.P
+- data := ctxt.loader.Data(rsrcsym)
- size := len(data)
-+ var size int
-+ for i := range rsrcsyms {
-+ size += len(ctxt.loader.Syms[rsrcsyms[i]].P)
+- h := pefile.addSection(".rsrc", size, size)
++ var size int64
++ for _, rsrcsym := range rsrcsyms {
++ size += ctxt.loader.SymSize(rsrcsym)
+ }
- h := pefile.addSection(".rsrc", size, size)
++ h := pefile.addSection(".rsrc", int(size), int(size))
h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA
h.checkOffset(ctxt.Out.Offset())
- // relocation
-- for ri := range rsrc.R {
-- r := &rsrc.R[ri]
-- p := data[r.Off:]
-- val := uint32(int64(h.virtualAddress) + r.Add)
+- relocs := ctxt.loader.Relocs(rsrcsym)
+- for i := 0; i < relocs.Count(); i++ {
+- r := relocs.At(i)
+- p := data[r.Off():]
+- val := uint32(int64(h.virtualAddress) + r.Add())
-
- // 32-bit little-endian
- p[0] = byte(val)
@@ -107,19 +122,31 @@ index ec5b6d5f52..29094fe8ed 100644
- p[1] = byte(val >> 8)
- p[2] = byte(val >> 16)
- p[3] = byte(val >> 24)
-+ for i := range rsrcsyms {
-+ rsrc := ctxt.loader.Syms[rsrcsyms[i]]
-+ splitResources := strings.Contains(rsrc.Name, ".rsrc$")
-+ for ri := range rsrc.R {
-+ r := &rsrc.R[ri]
-+ p := rsrc.P[r.Off:]
-+ val := uint32(int64(h.virtualAddress) + r.Add)
++ for _, rsrcsym := range rsrcsyms {
++ // A split resource happens when the actual resource data and its relocations are
++ // split across multiple sections, denoted by a $01 or $02 at the end of the .rsrc
++ // section name.
++ splitResources := strings.Contains(ctxt.loader.SymName(rsrcsym), ".rsrc$")
++ relocs := ctxt.loader.Relocs(rsrcsym)
++ data := ctxt.loader.Data(rsrcsym)
++ for ri := 0; ri < relocs.Count(); ri++ {
++ r := relocs.At(ri)
++ p := data[r.Off():]
++ val := uint32(int64(h.virtualAddress) + r.Add())
+ if splitResources {
-+ val += uint32(len(rsrc.P))
++ // If we're a split resource section, and that section has relocation
++ // symbols, then the data that it points to doesn't actually begin at
++ // the virtual address listed in this current section, but rather
++ // begins at the section immediately after this one. So, in order to
++ // calculate the proper virtual address of the data it's pointing to,
++ // we have to add the length of this section to the virtual address.
++ // This works because .rsrc sections are divided into two (but not more)
++ // of these sections.
++ val += uint32(len(data))
+ }
+ binary.LittleEndian.PutUint32(p, val)
+ }
-+ ctxt.Out.Write(rsrc.P)
++ ctxt.Out.Write(data)
}
-
- ctxt.Out.Write(data)
@@ -132,19 +159,22 @@ index ec5b6d5f52..29094fe8ed 100644
}
diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
-index b60b84ce9f..08832ba552 100644
+index 1e6f978531..a5c025de8f 100644
--- a/src/cmd/link/internal/loadpe/ldpe.go
+++ b/src/cmd/link/internal/loadpe/ldpe.go
-@@ -158,7 +158,7 @@ func makeUpdater(l *loader.Loader, bld *loader.SymbolBuilder, s loader.Sym) *loa
+@@ -157,8 +157,9 @@ func makeUpdater(l *loader.Loader, bld *loader.SymbolBuilder, s loader.Sym) *loa
+
// Load loads the PE file pn from input.
// Symbols are written into syms, and a slice of the text symbols is returned.
- // If an .rsrc section is found, its symbol is returned as rsrc.
+-// If an .rsrc section is found, its symbol is 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) {
++// 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) {
lookup := func(name string, version int) (*loader.SymbolBuilder, loader.Sym) {
s := l.LookupOrCreateSym(name, version)
sb := l.MakeSymbolUpdater(s)
-@@ -176,7 +176,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -176,7 +177,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
// TODO: replace pe.NewFile with pe.Load (grep for "add Load function" in debug/pe for details)
f, err := pe.NewFile(sr)
if err != nil {
@@ -153,7 +183,7 @@ index b60b84ce9f..08832ba552 100644
}
defer f.Close()
-@@ -211,21 +211,21 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -211,21 +212,21 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
bld.SetType(sym.STEXT)
default:
@@ -179,7 +209,7 @@ index b60b84ce9f..08832ba552 100644
}
}
-@@ -246,22 +246,23 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -246,22 +247,23 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
continue
}
@@ -206,7 +236,7 @@ index b60b84ce9f..08832ba552 100644
}
rSym := gosym
-@@ -271,11 +272,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -271,11 +273,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
var rType objabi.RelocType
switch arch.Family {
default:
@@ -220,7 +250,7 @@ index b60b84ce9f..08832ba552 100644
case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
-@@ -302,7 +303,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -302,7 +304,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
case sys.ARM:
switch r.Type {
default:
@@ -229,27 +259,19 @@ index b60b84ce9f..08832ba552 100644
case IMAGE_REL_ARM_SECREL:
rType = objabi.R_PCREL
-@@ -324,7 +325,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -323,8 +325,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+
// ld -r could generate multiple section symbols for the
// same section but with different values, we have to take
- // that into account
+- // that into account
- if issect(pesym) {
++ // that into account, or in the case of split resources,
++ // the section and its symbols are split into two sections.
+ if issect(pesym) || splitResources {
rAdd += int64(pesym.Value)
}
-@@ -333,6 +334,10 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
- rel.SetSiz(rSize)
- rel.SetSym(rSym)
- rel.SetAdd(rAdd)
-+
-+ if splitResources {
-+ l.SetAttrReachable(rSym, true)
-+ }
- }
-
- sb.SortRelocs()
-@@ -346,7 +351,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -346,7 +349,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
name, err := pesym.FullName(f.StringTable)
if err != nil {
@@ -258,7 +280,7 @@ index b60b84ce9f..08832ba552 100644
}
if name == "" {
continue
-@@ -373,7 +378,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -384,7 +387,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
bld, s, err := readpesym(l, arch, l.LookupOrCreateSym, f, pesym, sectsyms, localSymVersion)
if err != nil {
@@ -267,7 +289,7 @@ index b60b84ce9f..08832ba552 100644
}
if pesym.SectionNumber == 0 { // extern
-@@ -391,14 +396,14 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -402,14 +405,14 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
} else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {
sect = f.Sections[pesym.SectionNumber-1]
if _, found := sectsyms[sect]; !found {
@@ -285,7 +307,7 @@ index b60b84ce9f..08832ba552 100644
}
if l.OuterSym(s) != 0 {
-@@ -407,7 +412,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -418,7 +421,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
}
outerName := l.SymName(l.OuterSym(s))
sectName := l.SymName(sectsyms[sect])
@@ -294,7 +316,7 @@ index b60b84ce9f..08832ba552 100644
}
bld = makeUpdater(l, bld, s)
-@@ -418,7 +423,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -429,7 +432,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
bld.SetSize(4)
if l.SymType(sectsym) == sym.STEXT {
if bld.External() && !bld.DuplicateOK() {
@@ -303,7 +325,7 @@ index b60b84ce9f..08832ba552 100644
}
bld.SetExternal(true)
}
-@@ -435,7 +440,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
+@@ -446,7 +449,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
if l.SymType(s) == sym.STEXT {
for ; s != 0; s = l.SubSym(s) {
if l.AttrOnList(s) {
diff --git a/go-patches/0003-cmd-link-ignore-SEH-marking-on-PE-objects.patch b/go-patches/0003-cmd-link-ignore-SEH-marking-on-PE-objects.patch
deleted file mode 100644
index e5c86f88..00000000
--- a/go-patches/0003-cmd-link-ignore-SEH-marking-on-PE-objects.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From e8142ab5e3b3a513683a8e3792e6197644547981 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 8 Nov 2020 03:20:36 +0100
-Subject: [PATCH 03/14] cmd/link: ignore SEH marking on PE objects
-
-Microsoft's linker looks at whether all input objects have an empty
-section called @feat.00. If all of them do, then it enables SEH;
-otherwise it doesn't enable that feature. So, since around the Windows
-XP SP2 era, most tools that make PE objects just tack on that section,
-so that it won't gimp Microsoft's linker logic. Go doesn't support SEH,
-so in theory, none of this really matters to us. But actually, if the
-linker tries to ingest an object with @feat.00 -- which are produced by
-LLVM's resource compiler, for example -- it chokes because of the
-IMAGE_SYM_ABSOLUTE section that it doesn't know how to deal with. Since
-@feat.00 is just a marking anyway, skip IMAGE_SYM_ABSOLUTE sections that
-are called @feat.00.
-
-Change-Id: I1d7bfcf6001186c53e2c487c5ac251ca65efefee
----
- src/cmd/link/internal/loadpe/ldpe.go | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
-index 5839a6a5f2..b60b84ce9f 100644
---- a/src/cmd/link/internal/loadpe/ldpe.go
-+++ b/src/cmd/link/internal/loadpe/ldpe.go
-@@ -6,6 +6,7 @@
- package loadpe
-
- import (
-+ "bytes"
- "cmd/internal/bio"
- "cmd/internal/objabi"
- "cmd/internal/sys"
-@@ -359,6 +360,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
- if pesym.SectionNumber == IMAGE_SYM_DEBUG {
- continue
- }
-+ if pesym.SectionNumber == IMAGE_SYM_ABSOLUTE && bytes.Equal(pesym.Name[:], []byte("@feat.00")) {
-+ continue
-+ }
- var sect *pe.Section
- if pesym.SectionNumber > 0 {
- sect = f.Sections[pesym.SectionNumber-1]
---
-2.29.2
-
diff --git a/go-patches/0004-cmd-link-do-not-mark-resource-section-as-writable.patch b/go-patches/0004-cmd-link-do-not-mark-resource-section-as-writable.patch
deleted file mode 100644
index 1d9cb434..00000000
--- a/go-patches/0004-cmd-link-do-not-mark-resource-section-as-writable.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8255e115f325a58fd4746741f9f35c2f54d70d63 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 8 Nov 2020 11:11:27 +0100
-Subject: [PATCH 04/14] cmd/link: do not mark resource section as writable
-
-Resources are immutable, and all other linkers set this section to be
-read-only and not read-write. Fix this oversight by rmoving the writable
-flag.
-
-Change-Id: Ib441bde6620be2000f1685df1ea7bfaebdbe7860
----
- src/cmd/link/internal/ld/pe.go | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
-index c9cb25dbe5..ec5b6d5f52 100644
---- a/src/cmd/link/internal/ld/pe.go
-+++ b/src/cmd/link/internal/ld/pe.go
-@@ -1482,7 +1482,7 @@ func addpersrc(ctxt *Link) {
- data := rsrc.P
- size := len(data)
- h := pefile.addSection(".rsrc", size, size)
-- h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
-+ h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA
- h.checkOffset(ctxt.Out.Offset())
-
- // relocation
---
-2.29.2
-
diff --git a/go-patches/0006-Revert-release-branch.go1.15-runtime-detect-services.patch b/go-patches/0006-Revert-release-branch.go1.15-runtime-detect-services.patch
deleted file mode 100644
index cb21af9f..00000000
--- a/go-patches/0006-Revert-release-branch.go1.15-runtime-detect-services.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From e6b4c1b3beb4f843ed40abead27c8132d29a0db8 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Fri, 11 Sep 2020 13:04:11 +0200
-Subject: [PATCH 06/14] Revert "[release-branch.go1.15] runtime: detect
- services in signal handler"
-
-This reverts commit b1253d24e159129c778377c3a2a0bde15904a417.
----
- src/runtime/os_windows.go | 73 +++------------------------------------
- 1 file changed, 4 insertions(+), 69 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index 769197db46..a584ada702 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -36,10 +36,7 @@ const (
- //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
--//go:cgo_import_dynamic runtime._OpenProcess OpenProcess%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
--//go:cgo_import_dynamic runtime._ProcessIdToSessionId ProcessIdToSessionId%2 "kernel32.dll"
--//go:cgo_import_dynamic runtime._QueryFullProcessImageNameA QueryFullProcessImageNameA%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
-@@ -87,10 +84,7 @@ var (
- _SetThreadContext,
- _LoadLibraryW,
- _LoadLibraryA,
-- _OpenProcess,
- _PostQueuedCompletionStatus,
-- _ProcessIdToSessionId,
-- _QueryFullProcessImageNameA,
- _QueryPerformanceCounter,
- _QueryPerformanceFrequency,
- _ResumeThread,
-@@ -134,8 +128,7 @@ var (
- // Load ntdll.dll manually during startup, otherwise Mingw
- // links wrong printf function to cgo executable (see issue
- // 12030 for details).
-- _NtWaitForSingleObject stdFunction
-- _NtQueryInformationProcess stdFunction
-+ _NtWaitForSingleObject stdFunction
-
- // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
- _timeBeginPeriod,
-@@ -262,7 +255,6 @@ func loadOptionalSyscalls() {
- throw("ntdll.dll not found")
- }
- _NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
-- _NtQueryInformationProcess = windowsFindfunc(n32, []byte("NtQueryInformationProcess\000"))
-
- if GOARCH == "arm" {
- _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
-@@ -1003,63 +995,6 @@ func usleep(us uint32) {
- onosstack(usleep2Addr, 10*us)
- }
-
--// isWindowsService returns whether the process is currently executing as a
--// Windows service. The below technique looks a bit hairy, but it's actually
--// exactly what the .NET framework does for the similarly named function:
--// https://github.com/dotnet/extensions/blob/f4066026ca06984b07e90e61a6390ac38152ba93/src/Hosting/WindowsServices/src/WindowsServiceHelpers.cs#L26-L31
--// Specifically, it looks up whether the parent process has session ID zero
--// and is called "services".
--func isWindowsService() bool {
-- const (
-- _CURRENT_PROCESS = ^uintptr(0)
-- _PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
-- )
-- // pbi is a PROCESS_BASIC_INFORMATION struct, where we just care about
-- // the 6th pointer inside of it, which contains the pid of the process
-- // parent:
-- // https://github.com/wine-mirror/wine/blob/42cb7d2ad1caba08de235e6319b9967296b5d554/include/winternl.h#L1294
-- var pbi [6]uintptr
-- var pbiLen uint32
-- err := stdcall5(_NtQueryInformationProcess, _CURRENT_PROCESS, 0, uintptr(unsafe.Pointer(&pbi[0])), uintptr(unsafe.Sizeof(pbi)), uintptr(unsafe.Pointer(&pbiLen)))
-- if err != 0 {
-- return false
-- }
-- var psid uint32
-- err = stdcall2(_ProcessIdToSessionId, pbi[5], uintptr(unsafe.Pointer(&psid)))
-- if err == 0 || psid != 0 {
-- return false
-- }
-- pproc := stdcall3(_OpenProcess, _PROCESS_QUERY_LIMITED_INFORMATION, 0, pbi[5])
-- if pproc == 0 {
-- return false
-- }
-- defer stdcall1(_CloseHandle, pproc)
-- // exeName gets the path to the executable image of the parent process
-- var exeName [261]byte
-- exeNameLen := uint32(len(exeName) - 1)
-- err = stdcall4(_QueryFullProcessImageNameA, pproc, 0, uintptr(unsafe.Pointer(&exeName[0])), uintptr(unsafe.Pointer(&exeNameLen)))
-- if err == 0 || exeNameLen == 0 {
-- return false
-- }
-- servicesLower := "services.exe"
-- servicesUpper := "SERVICES.EXE"
-- i := int(exeNameLen) - 1
-- j := len(servicesLower) - 1
-- if i < j {
-- return false
-- }
-- for {
-- if j == -1 {
-- return i == -1 || exeName[i] == '\\'
-- }
-- if exeName[i] != servicesLower[j] && exeName[i] != servicesUpper[j] {
-- return false
-- }
-- i--
-- j--
-- }
--}
--
- func ctrlhandler1(_type uint32) uint32 {
- var s uint32
-
-@@ -1075,9 +1010,9 @@ func ctrlhandler1(_type uint32) uint32 {
- if sigsend(s) {
- return 1
- }
-- if !islibrary && !isarchive && !isWindowsService() {
-- // Only exit the program if we don't have a DLL or service.
-- // See https://golang.org/issues/35965 and https://golang.org/issues/40167
-+ if !islibrary && !isarchive {
-+ // Only exit the program if we don't have a DLL.
-+ // See https://golang.org/issues/35965.
- exit(2) // SIGINT, SIGTERM, etc
- }
- return 0
---
-2.29.2
-
diff --git a/go-patches/0007-runtime-do-not-explicitly-exit-on-ctrl-handler.patch b/go-patches/0007-runtime-do-not-explicitly-exit-on-ctrl-handler.patch
deleted file mode 100644
index 4db19853..00000000
--- a/go-patches/0007-runtime-do-not-explicitly-exit-on-ctrl-handler.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From af4eb34d920c0c727041ebf587e0de608068ed59 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Tue, 14 Jul 2020 01:41:03 -0600
-Subject: [PATCH 07/14] runtime: do not explicitly exit on ctrl handler
-
-The default ctrl+c handler should process exits in situations where it
-makes sense, like console apps, but not in situations where it doesn't,
-like libraries or services. Therefore, we should remove the exit(2) so
-that the default handler is used for this. This also uses the more
-proper windows exit code of STATUS_CONTROL_C_EXIT, with the base case
-handler installed by KernelBase.dll. In particular, this helps in the
-case of services, which previously would terminate when receiving
-shutdown signals, instead of passing them onward to the service program.
-In this CL, contrary to CL 244959, we do not need to special case
-services with expensive detection algorithms, or rely on hard-coded
-library/archive flags.
-
-Fixes #40167.
-Fixes #40074.
-
-Change-Id: I9bf6ed6f65cefeff754d270aa33fa4df8d0b451f
-Reviewed-on: https://go-review.googlesource.com/c/go/+/243597
-Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
-TryBot-Result: Gobot Gobot <gobot@golang.org>
-Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
-Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
----
- src/runtime/os_windows.go | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index a584ada702..a62e941229 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -1010,11 +1010,6 @@ func ctrlhandler1(_type uint32) uint32 {
- if sigsend(s) {
- return 1
- }
-- if !islibrary && !isarchive {
-- // Only exit the program if we don't have a DLL.
-- // See https://golang.org/issues/35965.
-- exit(2) // SIGINT, SIGTERM, etc
-- }
- return 0
- }
-
---
-2.29.2
-
diff --git a/go-patches/0008-runtime-allow-callback-functions-with-up-to-8-argume.patch b/go-patches/0008-runtime-allow-callback-functions-with-up-to-8-argume.patch
deleted file mode 100644
index 0af97ce2..00000000
--- a/go-patches/0008-runtime-allow-callback-functions-with-up-to-8-argume.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 5a7c808cbacb8c0477395c5656c1eba3ef38cd6e Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Tue, 10 Nov 2020 21:42:36 +0100
-Subject: [PATCH 08/14] runtime: allow callback functions with up to 8
- arguments on windows/arm
-
-Previously, windows/arm programs would abort when trying to use
-functions that took callbacks with more than 4 arguments. This caused
-issues when using SetWinEventHook, which receives 7 arguments. Add 4
-more by pulling them off the stack.
-
-Change-Id: I15a6a3168237fd8bb1128cc2c11ff2d900d665d2
----
- src/runtime/sys_windows_arm.s | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
-diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
-index 256b5ff7f0..049c69ec88 100644
---- a/src/runtime/sys_windows_arm.s
-+++ b/src/runtime/sys_windows_arm.s
-@@ -315,10 +315,14 @@ GLOBL runtime·cbctxts(SB), NOPTR, $4
-
- TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
- MOVM.DB.W [R4-R11, R14], (R13) // push {r4-r11, lr}
-- SUB $36, R13 // space for locals
-+ SUB $52, R13 // space for locals
-
-- // save callback arguments to stack. We currently support up to 4 arguments
-+ // save callback arguments to stack. We currently support up to 8 arguments
- ADD $16, R13, R4
-+ MOVM.IA.W [R0-R3], (R4)
-+ // the remaining 4 arguments are on the stack
-+ ADD $88, R13, R5
-+ MOVM.IA (R5), [R0-R3]
- MOVM.IA [R0-R3], (R4)
-
- // load cbctxts[i]. The trampoline in zcallback_windows.s puts the callback
-@@ -330,8 +334,8 @@ TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
- MOVW wincallbackcontext_argsize(R4), R5
- MOVW wincallbackcontext_gobody(R4), R4
-
-- // we currently support up to 4 arguments
-- CMP $(4 * 4), R5
-+ // we currently support up to 8 arguments
-+ CMP $(4 * 8), R5
- BL.GT runtime·abort(SB)
-
- // extend argsize by size of return value
-@@ -351,7 +355,7 @@ TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
- SUB $4, R1 // offset to return value
- MOVW R1<<0(R0), R0 // load return value
-
-- ADD $36, R13 // free locals
-+ ADD $52, R13 // free locals
- MOVM.IA.W (R13), [R4-R11, R15] // pop {r4-r11, pc}
-
- // uint32 tstart_stdcall(M *newm);
---
-2.29.2
-
diff --git a/go-patches/0009-runtime-use-CreateWaitableTimerEx-to-implement-uslee.patch b/go-patches/0009-runtime-use-CreateWaitableTimerEx-to-implement-uslee.patch
deleted file mode 100644
index 83647c59..00000000
--- a/go-patches/0009-runtime-use-CreateWaitableTimerEx-to-implement-uslee.patch
+++ /dev/null
@@ -1,419 +0,0 @@
-From 1a163f2e676e4664f2db3f614eb4168bda9d4fd8 Mon Sep 17 00:00:00 2001
-From: Alex Brainman <alex.brainman@gmail.com>
-Date: Sun, 19 Jul 2020 16:06:48 +1000
-Subject: [PATCH 09/14] runtime: use CreateWaitableTimerEx to implement usleep
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-@jstarks suggested that recent versions of Windows provide access to high resolution timers. See
-
-https://github.com/golang/go/issues/8687#issuecomment-656259353
-
-for details.
-
-I tried to run this C program on my Windows 10 computer
-
-```
- #include <stdio.h>
- #include <Windows.h>
-
- #pragma comment(lib, "Winmm.lib")
-
-// Apparently this is already defined when I use msvc cl.
-//#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002;
-
-int usleep(HANDLE timer, LONGLONG d) {
- LARGE_INTEGER liDueTime;
- DWORD ret;
- LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
- LARGE_INTEGER Frequency;
-
- QueryPerformanceFrequency(&Frequency);
- QueryPerformanceCounter(&StartingTime);
-
- liDueTime.QuadPart = d;
- liDueTime.QuadPart = liDueTime.QuadPart * 10; // us into 100 of ns units
- liDueTime.QuadPart = -liDueTime.QuadPart; // negative for relative dure time
-
- if (!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, 0)) {
- printf("SetWaitableTimer failed: errno=%d\n", GetLastError());
- return 1;
- }
-
- ret = WaitForSingleObject(timer, INFINITE);
- if (ret != WAIT_OBJECT_0) {
- printf("WaitForSingleObject failed: ret=%d errno=%d\n", ret, GetLastError());
- return 1;
- }
-
- QueryPerformanceCounter(&EndingTime);
- ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
- ElapsedMicroseconds.QuadPart *= 1000000;
- ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
-
- printf("delay is %lld us - slept for %lld us\n", d, ElapsedMicroseconds.QuadPart);
-
- return 0;
-}
-
-int testTimer(DWORD createFlag)
-{
- HANDLE timer;
-
- timer = CreateWaitableTimerEx(NULL, NULL, createFlag, TIMER_ALL_ACCESS);
- if (timer == NULL) {
- printf("CreateWaitableTimerEx failed: errno=%d\n", GetLastError());
- return 1;
- }
-
- usleep(timer, 1000LL);
- usleep(timer, 100LL);
- usleep(timer, 10LL);
- usleep(timer, 1LL);
-
- CloseHandle(timer);
-
- return 0;
-}
-
-int main()
-{
- printf("\n1. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is off\n");
- testTimer(0);
-
- printf("\n2. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is off\n");
- testTimer(CREATE_WAITABLE_TIMER_HIGH_RESOLUTION);
-
- timeBeginPeriod(1);
-
- printf("\n3. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is on\n");
- testTimer(0);
-
- printf("\n4. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is on\n");
- testTimer(CREATE_WAITABLE_TIMER_HIGH_RESOLUTION);
-}
-```
-
-and I see this output
-
-```
-1. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is off
-delay is 1000 us - slept for 4045 us
-delay is 100 us - slept for 3915 us
-delay is 10 us - slept for 3291 us
-delay is 1 us - slept for 2234 us
-
-2. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is off
-delay is 1000 us - slept for 1076 us
-delay is 100 us - slept for 569 us
-delay is 10 us - slept for 585 us
-delay is 1 us - slept for 17 us
-
-3. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is off - timeBeginPeriod is on
-delay is 1000 us - slept for 742 us
-delay is 100 us - slept for 893 us
-delay is 10 us - slept for 414 us
-delay is 1 us - slept for 920 us
-
-4. CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is on - timeBeginPeriod is on
-delay is 1000 us - slept for 1466 us
-delay is 100 us - slept for 559 us
-delay is 10 us - slept for 535 us
-delay is 1 us - slept for 5 us
-```
-
-That shows, that indeed using CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
-will provide sleeps as low as about 500 microseconds, while our
-current approach provides about 1 millisecond sleep.
-
-New approach also does not require for timeBeginPeriod to be on,
-so this change solves long standing problem with go programs draining
-laptop battery, because it calls timeBeginPeriod.
-
-This change will only run on systems where
-CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available. If not
-available, the runtime will fallback to original code that uses
-timeBeginPeriod.
-
-This is how this change affects benchmark reported in issue #14790
-
-name               old time/op  new time/op  delta
-ChanToSyscallPing  1.05ms ± 2%  0.68ms ±11%  -35.43%  (p=0.000 n=10+10)
-
-The benchmark was run with GOMAXPROCS set to 1.
-
-Fixes #8687
-Updates #14790
-
-Change-Id: I5b97ba58289c088c17c05292e12e45285c467eae
-Reviewed-on: https://go-review.googlesource.com/c/go/+/248699
-Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
-TryBot-Result: Go Bot <gobot@golang.org>
-Trust: Alex Brainman <alex.brainman@gmail.com>
-Reviewed-by: Austin Clements <austin@google.com>
----
- src/runtime/os_windows.go | 73 ++++++++++++++++++++++++++++++++-
- src/runtime/sys_windows_386.s | 36 ++++++++++++++++
- src/runtime/sys_windows_amd64.s | 32 +++++++++++++++
- src/runtime/sys_windows_arm.s | 5 +++
- 4 files changed, 144 insertions(+), 2 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index a62e941229..9dd140c952 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -21,6 +21,7 @@ const (
- //go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
- //go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
-+//go:cgo_import_dynamic runtime._CreateWaitableTimerExW CreateWaitableTimerExW%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
- //go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
-@@ -68,6 +69,7 @@ var (
- _CreateIoCompletionPort,
- _CreateThread,
- _CreateWaitableTimerA,
-+ _CreateWaitableTimerExW,
- _DuplicateHandle,
- _ExitProcess,
- _FreeEnvironmentStringsW,
-@@ -151,6 +153,8 @@ type mOS struct {
- waitsema uintptr // semaphore for parking on locks
- resumesema uintptr // semaphore to indicate suspend/resume
-
-+ highResTimer uintptr // high resolution timer handle used in usleep
-+
- // preemptExtLock synchronizes preemptM with entry/exit from
- // external C code.
- //
-@@ -402,11 +406,21 @@ const osRelaxMinNS = 60 * 1e6
- // osRelax is called by the scheduler when transitioning to and from
- // all Ps being idle.
- //
--// On Windows, it adjusts the system-wide timer resolution. Go needs a
-+// Some versions of Windows have high resolution timer. For those
-+// versions osRelax is noop.
-+// For Windows versions without high resolution timer, osRelax
-+// adjusts the system-wide timer resolution. Go needs a
- // high resolution timer while running and there's little extra cost
- // if we're already using the CPU, but if all Ps are idle there's no
- // need to consume extra power to drive the high-res timer.
- func osRelax(relax bool) uint32 {
-+ if haveHighResTimer {
-+ // If the high resolution timer is available, the runtime uses the timer
-+ // to sleep for short durations. This means there's no need to adjust
-+ // the global clock frequency.
-+ return 0
-+ }
-+
- if relax {
- return uint32(stdcall1(_timeEndPeriod, 1))
- } else {
-@@ -414,6 +428,42 @@ func osRelax(relax bool) uint32 {
- }
- }
-
-+// haveHighResTimer indicates that the CreateWaitableTimerEx
-+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available.
-+var haveHighResTimer = false
-+
-+// createHighResTimer calls CreateWaitableTimerEx with
-+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag to create high
-+// resolution timer. createHighResTimer returns new timer
-+// handle or 0, if CreateWaitableTimerEx failed.
-+func createHighResTimer() uintptr {
-+ const (
-+ // As per @jstarks, see
-+ // https://github.com/golang/go/issues/8687#issuecomment-656259353
-+ _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
-+
-+ _SYNCHRONIZE = 0x00100000
-+ _TIMER_QUERY_STATE = 0x0001
-+ _TIMER_MODIFY_STATE = 0x0002
-+ )
-+ return stdcall4(_CreateWaitableTimerExW, 0, 0,
-+ _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
-+ _SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
-+}
-+
-+func initHighResTimer() {
-+ if GOARCH == "arm" {
-+ // TODO: Not yet implemented.
-+ return
-+ }
-+ h := createHighResTimer()
-+ if h != 0 {
-+ haveHighResTimer = true
-+ usleep2Addr = unsafe.Pointer(funcPC(usleep2HighRes))
-+ stdcall1(_CloseHandle, h)
-+ }
-+}
-+
- func osinit() {
- asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
- usleep2Addr = unsafe.Pointer(funcPC(usleep2))
-@@ -429,6 +479,7 @@ func osinit() {
-
- stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
-
-+ initHighResTimer()
- timeBeginPeriodRetValue = osRelax(false)
-
- ncpu = getproccount()
-@@ -844,9 +895,20 @@ func minit() {
- var thandle uintptr
- stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
-
-+ // Configure usleep timer, if possible.
-+ var timer uintptr
-+ if haveHighResTimer {
-+ timer = createHighResTimer()
-+ if timer == 0 {
-+ print("runtime: CreateWaitableTimerEx failed; errno=", getlasterror(), "\n")
-+ throw("CreateWaitableTimerEx when creating timer failed")
-+ }
-+ }
-+
- mp := getg().m
- lock(&mp.threadLock)
- mp.thread = thandle
-+ mp.highResTimer = timer
- unlock(&mp.threadLock)
-
- // Query the true stack base from the OS. Currently we're
-@@ -884,6 +946,10 @@ func unminit() {
- lock(&mp.threadLock)
- stdcall1(_CloseHandle, mp.thread)
- mp.thread = 0
-+ if mp.highResTimer != 0 {
-+ stdcall1(_CloseHandle, mp.highResTimer)
-+ mp.highResTimer = 0
-+ }
- unlock(&mp.threadLock)
- }
-
-@@ -976,9 +1042,12 @@ func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
- return stdcall(fn)
- }
-
--// in sys_windows_386.s and sys_windows_amd64.s
-+// In sys_windows_386.s and sys_windows_amd64.s.
- func onosstack(fn unsafe.Pointer, arg uint32)
-+
-+// These are not callable functions. They should only be called via onosstack.
- func usleep2(usec uint32)
-+func usleep2HighRes(usec uint32)
- func switchtothread()
-
- var usleep2Addr unsafe.Pointer
-diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
-index 9e1f40925d..4ac1527ab1 100644
---- a/src/runtime/sys_windows_386.s
-+++ b/src/runtime/sys_windows_386.s
-@@ -428,6 +428,42 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
- MOVL BP, SP
- RET
-
-+// Runs on OS stack. duration (in 100ns units) is in BX.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
-+ // Want negative 100ns units.
-+ NEGL BX
-+ MOVL $-1, hi-4(SP)
-+ MOVL BX, lo-8(SP)
-+
-+ get_tls(CX)
-+ MOVL g(CX), CX
-+ MOVL g_m(CX), CX
-+ MOVL (m_mOS+mOS_highResTimer)(CX), CX
-+ MOVL CX, saved_timer-12(SP)
-+
-+ MOVL $0, fResume-16(SP)
-+ MOVL $0, lpArgToCompletionRoutine-20(SP)
-+ MOVL $0, pfnCompletionRoutine-24(SP)
-+ MOVL $0, lPeriod-28(SP)
-+ LEAL lo-8(SP), BX
-+ MOVL BX, lpDueTime-32(SP)
-+ MOVL CX, hTimer-36(SP)
-+ MOVL SP, BP
-+ MOVL runtime·_SetWaitableTimer(SB), AX
-+ CALL AX
-+ MOVL BP, SP
-+
-+ MOVL $0, ptime-28(SP)
-+ MOVL $0, alertable-32(SP)
-+ MOVL saved_timer-12(SP), CX
-+ MOVL CX, handle-36(SP)
-+ MOVL SP, BP
-+ MOVL runtime·_NtWaitForSingleObject(SB), AX
-+ CALL AX
-+ MOVL BP, SP
-+
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT,$0
- MOVL SP, BP
-diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
-index 6c8eecd4e7..847542592b 100644
---- a/src/runtime/sys_windows_amd64.s
-+++ b/src/runtime/sys_windows_amd64.s
-@@ -457,6 +457,38 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48
- MOVQ 40(SP), SP
- RET
-
-+// Runs on OS stack. duration (in 100ns units) is in BX.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
-+ MOVQ SP, AX
-+ ANDQ $~15, SP // alignment as per Windows requirement
-+ MOVQ AX, 64(SP)
-+
-+ get_tls(CX)
-+ MOVQ g(CX), CX
-+ MOVQ g_m(CX), CX
-+ MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer
-+ MOVQ CX, 48(SP) // save hTimer for later
-+ // Want negative 100ns units.
-+ NEGQ BX
-+ LEAQ 56(SP), DX // lpDueTime
-+ MOVQ BX, (DX)
-+ MOVQ $0, R8 // lPeriod
-+ MOVQ $0, R9 // pfnCompletionRoutine
-+ MOVQ $0, AX
-+ MOVQ AX, 32(SP) // lpArgToCompletionRoutine
-+ MOVQ AX, 40(SP) // fResume
-+ MOVQ runtime·_SetWaitableTimer(SB), AX
-+ CALL AX
-+
-+ MOVQ 48(SP), CX // handle
-+ MOVQ $0, DX // alertable
-+ MOVQ $0, R8 // ptime
-+ MOVQ runtime·_NtWaitForSingleObject(SB), AX
-+ CALL AX
-+
-+ MOVQ 64(SP), SP
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVQ SP, AX
-diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
-index 049c69ec88..eaceca4bc3 100644
---- a/src/runtime/sys_windows_arm.s
-+++ b/src/runtime/sys_windows_arm.s
-@@ -472,6 +472,11 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0
- MOVW R4, R13 // Restore SP
- MOVM.IA.W (R13), [R4, R15] // pop {R4, pc}
-
-+// Runs on OS stack. Duration (in 100ns units) is in R0.
-+// TODO: neeeds to be implemented properly.
-+TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0
-+ B runtime·abort(SB)
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVM.DB.W [R4, R14], (R13) // push {R4, lr}
---
-2.29.2
-
diff --git a/go-patches/0010-runtime-allow-for-usleep2HighRes-to-run-without-TLS-.patch b/go-patches/0010-runtime-allow-for-usleep2HighRes-to-run-without-TLS-.patch
deleted file mode 100644
index 1c25f5b6..00000000
--- a/go-patches/0010-runtime-allow-for-usleep2HighRes-to-run-without-TLS-.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 1edac4879e2d4a36d339353c151cb7b9871e135f Mon Sep 17 00:00:00 2001
-From: Alex Brainman <alex.brainman@gmail.com>
-Date: Sat, 21 Nov 2020 14:56:26 +1100
-Subject: [PATCH 10/14] runtime: allow for usleep2HighRes to run without TLS
- setup
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This change adjusts usleep2HighRes so it does not crash when TLS is
-not configured. When g is not available, usleep2HighRes just calls
-usleep2 instead.
-
-Updates #8687
-
-Change-Id: Idbb80f7b71d1da350a6a7df7c49154eb1ffe29a8
----
- src/runtime/sys_windows_386.s | 11 ++++++++++-
- src/runtime/sys_windows_amd64.s | 11 ++++++++++-
- 2 files changed, 20 insertions(+), 2 deletions(-)
-
-diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
-index 4ac1527ab1..310c4008e5 100644
---- a/src/runtime/sys_windows_386.s
-+++ b/src/runtime/sys_windows_386.s
-@@ -430,12 +430,15 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
-
- // Runs on OS stack. duration (in 100ns units) is in BX.
- TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
-+ get_tls(CX)
-+ CMPL CX, $0
-+ JE gisnotset
-+
- // Want negative 100ns units.
- NEGL BX
- MOVL $-1, hi-4(SP)
- MOVL BX, lo-8(SP)
-
-- get_tls(CX)
- MOVL g(CX), CX
- MOVL g_m(CX), CX
- MOVL (m_mOS+mOS_highResTimer)(CX), CX
-@@ -464,6 +467,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36
-
- RET
-
-+gisnotset:
-+ // TLS is not configured. Call usleep2 instead.
-+ MOVL $runtime·usleep2(SB), AX
-+ CALL AX
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT,$0
- MOVL SP, BP
-diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
-index 847542592b..699a6e6ff2 100644
---- a/src/runtime/sys_windows_amd64.s
-+++ b/src/runtime/sys_windows_amd64.s
-@@ -459,11 +459,14 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48
-
- // Runs on OS stack. duration (in 100ns units) is in BX.
- TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
-+ get_tls(CX)
-+ CMPQ CX, $0
-+ JE gisnotset
-+
- MOVQ SP, AX
- ANDQ $~15, SP // alignment as per Windows requirement
- MOVQ AX, 64(SP)
-
-- get_tls(CX)
- MOVQ g(CX), CX
- MOVQ g_m(CX), CX
- MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer
-@@ -489,6 +492,12 @@ TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72
- MOVQ 64(SP), SP
- RET
-
-+gisnotset:
-+ // TLS is not configured. Call usleep2 instead.
-+ MOVQ $runtime·usleep2(SB), AX
-+ CALL AX
-+ RET
-+
- // Runs on OS stack.
- TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVQ SP, AX
---
-2.29.2
-
diff --git a/go-patches/0011-cmd-link-windows-arm-is-all-pie-so-mark-it-as-such.patch b/go-patches/0011-cmd-link-windows-arm-is-all-pie-so-mark-it-as-such.patch
deleted file mode 100644
index a2984678..00000000
--- a/go-patches/0011-cmd-link-windows-arm-is-all-pie-so-mark-it-as-such.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From fee7906e1a7e62b655bea0f25c921572ee29fc44 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Thu, 26 Nov 2020 22:38:45 +0100
-Subject: [PATCH 11/14] cmd/link: windows/arm is all pie, so mark it as such
-
-If the linker thinks that it's making an exe instead of a pie object, it
-won't apply relocations to the pclntab and we wind up with crashes like:
-
- Building Go toolchain2 using go_bootstrap and Go toolchain1.
- fatal error: minpc or maxpc invalid
- runtime: panic before malloc heap initialized
-
-This problem was already solved by darwin/arm64, so solve it the same
-way here for windows/arm.
-
-Fixes CL 228478.
-Updates #42786.
-
-Change-Id: I6d1db6907c131183649fc263ccca06783188f344
----
- src/cmd/link/internal/ld/config.go | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
-index 2373b500e3..83a8698289 100644
---- a/src/cmd/link/internal/ld/config.go
-+++ b/src/cmd/link/internal/ld/config.go
-@@ -35,7 +35,12 @@ func (mode *BuildMode) Set(s string) error {
- default:
- return fmt.Errorf("invalid buildmode: %q", s)
- case "exe":
-- *mode = BuildModeExe
-+ switch objabi.GOOS + "/" + objabi.GOARCH {
-+ case "windows/arm": // On these platforms, everything is PIE
-+ *mode = BuildModePIE
-+ default:
-+ *mode = BuildModeExe
-+ }
- case "pie":
- switch objabi.GOOS {
- case "aix", "android", "linux", "windows":
---
-2.29.2
-
diff --git a/go-patches/0012-runtime-adjust-address-calculation-in-identifying-ab.patch b/go-patches/0012-runtime-adjust-address-calculation-in-identifying-ab.patch
deleted file mode 100644
index 38fcbb9b..00000000
--- a/go-patches/0012-runtime-adjust-address-calculation-in-identifying-ab.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 8ec41fee1e6ef074ef74e56fe079c70c8a1d0548 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Fri, 27 Nov 2020 22:07:23 +0100
-Subject: [PATCH 12/14] runtime: adjust address calculation in identifying
- abort on windows/arm
-
-Apparently we're being called on arm 1 byte off, just like on 386 and
-amd64, so unify the handler for isAbortPC.
-
-Fixes #42859.
-Updates #29050.
-
-Change-Id: I97fffeb4a33d93ca3397ce1c9ba2b05137f391ca
----
- src/runtime/signal_windows.go | 13 +++----------
- 1 file changed, 3 insertions(+), 10 deletions(-)
-
-diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
-index d123276d3e..8db24fb805 100644
---- a/src/runtime/signal_windows.go
-+++ b/src/runtime/signal_windows.go
-@@ -43,16 +43,9 @@ func initExceptionHandler() {
- //
- //go:nosplit
- func isAbort(r *context) bool {
-- switch GOARCH {
-- case "386", "amd64":
-- // In the case of an abort, the exception IP is one byte after
-- // the INT3 (this differs from UNIX OSes).
-- return isAbortPC(r.ip() - 1)
-- case "arm":
-- return isAbortPC(r.ip())
-- default:
-- return false
-- }
-+ // In the case of an abort, the exception IP is one byte after
-+ // the INT3 (this differs from UNIX OSes).
-+ return isAbortPC(r.ip() - 1)
- }
-
- // isgoexception reports whether this exception should be translated
---
-2.29.2
-
diff --git a/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch b/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch
deleted file mode 100644
index a8eb403d..00000000
--- a/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch
+++ /dev/null
@@ -1,1275 +0,0 @@
-From 58e426bb8175959d7bf32ea7c87e51f4706b309b Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Mon, 30 Nov 2020 10:41:46 +0100
-Subject: [PATCH 13/14] cmd/compile: do not assume TST and TEQ set V on arm
-
-These replacement rules assume that TST and TEQ set V. But TST and
-TEQ do not set V. This is a problem because instructions like LT are
-actually checking for N!=V. But with TST and TEQ not setting V, LT
-doesn't do anything meaningful. It's possible to construct trivial
-miscompilations from this, such as:
-
- package main
-
- var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4}
-
- func main() {
- if x[0] > x[1] {
- panic("fail 1")
- }
- if x[2]&x[3] < 0 {
- panic("fail 2") // Fails here
- }
- }
-
-That first comparison sets V, via the CMP that subtracts the values
-causing the overflow. Then the second comparison operation thinks that
-it uses the result of TST, when it actually uses the V from CMP.
-
-Before this fix:
-
- TST R0, R1
- BLT loc_6C164
-
-After this fix:
-
- TST R0, R1
- BMI loc_6C164
-
-The BMI instruction checks the N flag, which TST sets. This commit
-fixes the issue by using [LG][TE]noov instead of vanilla [LG][TE], and
-also adds a test case for the direct issue.
-
-Fixes #42876.
-
-Change-Id: I13c62c88d18574247ad002b671b38d2d0b0fc6fa
-Reviewed-on: https://go-review.googlesource.com/c/go/+/274026
-Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
-TryBot-Result: Go Bot <gobot@golang.org>
-Reviewed-by: Cherry Zhang <cherryyz@google.com>
-Trust: Jason A. Donenfeld <Jason@zx2c4.com>
----
- src/cmd/compile/internal/ssa/gen/ARM.rules | 128 ++++-----
- src/cmd/compile/internal/ssa/rewriteARM.go | 306 ++++++++++-----------
- test/fixedbugs/issue42876.go | 18 ++
- 3 files changed, 235 insertions(+), 217 deletions(-)
- create mode 100644 test/fixedbugs/issue42876.go
-
-diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
-index ab8bd0e81e..c69084a701 100644
---- a/src/cmd/compile/internal/ssa/gen/ARM.rules
-+++ b/src/cmd/compile/internal/ssa/gen/ARM.rules
-@@ -1369,38 +1369,38 @@
- (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 -> (LT (TST x y) yes no)
--(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LT (TSTconst [c] x) yes no)
--(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftLL x y [c]) yes no)
--(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRL x y [c]) yes no)
--(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRA x y [c]) yes no)
--(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftLLreg x y z) yes no)
--(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRLreg x y z) yes no)
--(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRAreg x y z) yes no)
--(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LE (TST x y) yes no)
--(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LE (TSTconst [c] x) yes no)
--(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftLL x y [c]) yes no)
--(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRL x y [c]) yes no)
--(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRA x y [c]) yes no)
--(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftLLreg x y z) yes no)
--(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRLreg x y z) yes no)
--(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRAreg x y z) yes no)
--(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LT (TEQ x y) yes no)
--(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LT (TEQconst [c] x) yes no)
--(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftLL x y [c]) yes no)
--(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRL x y [c]) yes no)
--(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRA x y [c]) yes no)
--(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftLLreg x y z) yes no)
--(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRLreg x y z) yes no)
--(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRAreg x y z) yes no)
--(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LE (TEQ x y) yes no)
--(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LE (TEQconst [c] x) yes no)
--(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftLL x y [c]) yes no)
--(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRL x y [c]) yes no)
--(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRA x y [c]) yes no)
--(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftLLreg x y z) yes no)
--(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRLreg x y z) yes no)
--(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRAreg 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)
-@@ -1436,39 +1436,39 @@
- (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:(AND x y)) yes no) && l.Uses==1 -> (GT (TST x y) 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:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GT (TSTconst [c] x) yes no)
--(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftLL x y [c]) yes no)
--(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRL x y [c]) yes no)
--(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRA x y [c]) yes no)
--(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftLLreg x y z) yes no)
--(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRLreg x y z) yes no)
--(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRAreg x y z) yes no)
--(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GE (TST x y) yes no)
--(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GE (TSTconst [c] x) yes no)
--(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftLL x y [c]) yes no)
--(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRL x y [c]) yes no)
--(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRA x y [c]) yes no)
--(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftLLreg x y z) yes no)
--(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRLreg x y z) yes no)
--(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRAreg x y z) yes no)
--(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GT (TEQ x y) yes no)
--(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GT (TEQconst [c] x) yes no)
--(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftLL x y [c]) yes no)
--(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRL x y [c]) yes no)
--(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRA x y [c]) yes no)
--(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftLLreg x y z) yes no)
--(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRLreg x y z) yes no)
--(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRAreg x y z) yes no)
--(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GE (TEQ x y) yes no)
--(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GE (TEQconst [c] x) yes no)
--(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftLL x y [c]) yes no)
--(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRL x y [c]) yes no)
--(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRA x y [c]) yes no)
--(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftLLreg x y z) yes no)
--(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRLreg x y z) yes no)
--(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRAreg x y z) 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 [int64(read8(sym, off))])
- (MOVHUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))])
-diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
-index f55e542505..07653b78f8 100644
---- a/src/cmd/compile/internal/ssa/rewriteARM.go
-+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
-@@ -17278,7 +17278,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- // match: (GE (CMPconst [0] l:(AND x y)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TST x y) yes no)
-+ // result: (GEnoov (TST x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17299,14 +17299,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- break
- }
- // match: (GE (CMPconst [0] l:(ANDconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTconst [c] x) yes no)
-+ // result: (GEnoov (TSTconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17324,12 +17324,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftLL x y [c]) yes no)
-+ // result: (GEnoov (TSTshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17348,12 +17348,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftRL x y [c]) yes no)
-+ // result: (GEnoov (TSTshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17372,12 +17372,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftRA x y [c]) yes no)
-+ // result: (GEnoov (TSTshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17396,12 +17396,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftLLreg x y z) yes no)
-+ // result: (GEnoov (TSTshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17419,12 +17419,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftRLreg x y z) yes no)
-+ // result: (GEnoov (TSTshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17442,12 +17442,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TSTshiftRAreg x y z) yes no)
-+ // result: (GEnoov (TSTshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17465,12 +17465,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XOR x y)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQ x y) yes no)
-+ // result: (GEnoov (TEQ x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17491,14 +17491,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- break
- }
- // match: (GE (CMPconst [0] l:(XORconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQconst [c] x) yes no)
-+ // result: (GEnoov (TEQconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17516,12 +17516,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftLL x y [c]) yes no)
-+ // result: (GEnoov (TEQshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17540,12 +17540,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftRL x y [c]) yes no)
-+ // result: (GEnoov (TEQshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17564,12 +17564,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftRA x y [c]) yes no)
-+ // result: (GEnoov (TEQshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17588,12 +17588,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftLLreg x y z) yes no)
-+ // result: (GEnoov (TEQshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17611,12 +17611,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftRLreg x y z) yes no)
-+ // result: (GEnoov (TEQshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17634,12 +17634,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- // match: (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GE (TEQshiftRAreg x y z) yes no)
-+ // result: (GEnoov (TEQshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -17657,7 +17657,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGE, v0)
-+ b.resetWithControl(BlockARMGEnoov, v0)
- return true
- }
- case BlockARMGEnoov:
-@@ -18131,9 +18131,34 @@ func rewriteBlockARM(b *Block) bool {
- b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
-+ // match: (GT (CMPconst [0] l:(MULA x y a)) yes no)
-+ // cond: l.Uses==1
-+ // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
-+ for b.Controls[0].Op == OpARMCMPconst {
-+ v_0 := b.Controls[0]
-+ if v_0.AuxInt != 0 {
-+ break
-+ }
-+ l := v_0.Args[0]
-+ if l.Op != OpARMMULA {
-+ break
-+ }
-+ a := l.Args[2]
-+ x := l.Args[0]
-+ y := l.Args[1]
-+ if !(l.Uses == 1) {
-+ break
-+ }
-+ v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
-+ v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
-+ v1.AddArg2(x, y)
-+ v0.AddArg2(a, v1)
-+ b.resetWithControl(BlockARMGTnoov, v0)
-+ return true
-+ }
- // match: (GT (CMPconst [0] l:(AND x y)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TST x y) yes no)
-+ // result: (GTnoov (TST x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18154,39 +18179,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- break
- }
-- // match: (GT (CMPconst [0] l:(MULA x y a)) yes no)
-- // cond: l.Uses==1
-- // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
-- for b.Controls[0].Op == OpARMCMPconst {
-- v_0 := b.Controls[0]
-- if v_0.AuxInt != 0 {
-- break
-- }
-- l := v_0.Args[0]
-- if l.Op != OpARMMULA {
-- break
-- }
-- a := l.Args[2]
-- x := l.Args[0]
-- y := l.Args[1]
-- if !(l.Uses == 1) {
-- break
-- }
-- v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags)
-- v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type)
-- v1.AddArg2(x, y)
-- v0.AddArg2(a, v1)
-- b.resetWithControl(BlockARMGTnoov, v0)
-- return true
-- }
- // match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTconst [c] x) yes no)
-+ // result: (GTnoov (TSTconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18204,12 +18204,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftLL x y [c]) yes no)
-+ // result: (GTnoov (TSTshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18228,12 +18228,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftRL x y [c]) yes no)
-+ // result: (GTnoov (TSTshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18252,12 +18252,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftRA x y [c]) yes no)
-+ // result: (GTnoov (TSTshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18276,12 +18276,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftLLreg x y z) yes no)
-+ // result: (GTnoov (TSTshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18299,12 +18299,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftRLreg x y z) yes no)
-+ // result: (GTnoov (TSTshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18322,12 +18322,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TSTshiftRAreg x y z) yes no)
-+ // result: (GTnoov (TSTshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18345,12 +18345,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XOR x y)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQ x y) yes no)
-+ // result: (GTnoov (TEQ x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18371,14 +18371,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- break
- }
- // match: (GT (CMPconst [0] l:(XORconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQconst [c] x) yes no)
-+ // result: (GTnoov (TEQconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18396,12 +18396,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftLL x y [c]) yes no)
-+ // result: (GTnoov (TEQshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18420,12 +18420,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftRL x y [c]) yes no)
-+ // result: (GTnoov (TEQshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18444,12 +18444,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftRA x y [c]) yes no)
-+ // result: (GTnoov (TEQshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18468,12 +18468,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftLLreg x y z) yes no)
-+ // result: (GTnoov (TEQshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18491,12 +18491,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftRLreg x y z) yes no)
-+ // result: (GTnoov (TEQshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18514,12 +18514,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- // match: (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (GT (TEQshiftRAreg x y z) yes no)
-+ // result: (GTnoov (TEQshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -18537,7 +18537,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMGT, v0)
-+ b.resetWithControl(BlockARMGTnoov, v0)
- return true
- }
- case BlockARMGTnoov:
-@@ -19129,7 +19129,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- // match: (LE (CMPconst [0] l:(AND x y)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TST x y) yes no)
-+ // result: (LEnoov (TST x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19150,14 +19150,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- break
- }
- // match: (LE (CMPconst [0] l:(ANDconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTconst [c] x) yes no)
-+ // result: (LEnoov (TSTconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19175,12 +19175,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftLL x y [c]) yes no)
-+ // result: (LEnoov (TSTshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19199,12 +19199,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftRL x y [c]) yes no)
-+ // result: (LEnoov (TSTshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19223,12 +19223,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftRA x y [c]) yes no)
-+ // result: (LEnoov (TSTshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19247,12 +19247,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftLLreg x y z) yes no)
-+ // result: (LEnoov (TSTshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19270,12 +19270,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftRLreg x y z) yes no)
-+ // result: (LEnoov (TSTshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19293,12 +19293,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TSTshiftRAreg x y z) yes no)
-+ // result: (LEnoov (TSTshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19316,12 +19316,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XOR x y)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQ x y) yes no)
-+ // result: (LEnoov (TEQ x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19342,14 +19342,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- break
- }
- // match: (LE (CMPconst [0] l:(XORconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQconst [c] x) yes no)
-+ // result: (LEnoov (TEQconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19367,12 +19367,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftLL x y [c]) yes no)
-+ // result: (LEnoov (TEQshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19391,12 +19391,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftRL x y [c]) yes no)
-+ // result: (LEnoov (TEQshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19415,12 +19415,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftRA x y [c]) yes no)
-+ // result: (LEnoov (TEQshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19439,12 +19439,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftLLreg x y z) yes no)
-+ // result: (LEnoov (TEQshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19462,12 +19462,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftRLreg x y z) yes no)
-+ // result: (LEnoov (TEQshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19485,12 +19485,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- // match: (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LE (TEQshiftRAreg x y z) yes no)
-+ // result: (LEnoov (TEQshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -19508,7 +19508,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLE, v0)
-+ b.resetWithControl(BlockARMLEnoov, v0)
- return true
- }
- case BlockARMLEnoov:
-@@ -20009,7 +20009,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- // match: (LT (CMPconst [0] l:(AND x y)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TST x y) yes no)
-+ // result: (LTnoov (TST x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20030,14 +20030,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- break
- }
- // match: (LT (CMPconst [0] l:(ANDconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTconst [c] x) yes no)
-+ // result: (LTnoov (TSTconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20055,12 +20055,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftLL x y [c]) yes no)
-+ // result: (LTnoov (TSTshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20079,12 +20079,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftRL x y [c]) yes no)
-+ // result: (LTnoov (TSTshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20103,12 +20103,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftRA x y [c]) yes no)
-+ // result: (LTnoov (TSTshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20127,12 +20127,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftLLreg x y z) yes no)
-+ // result: (LTnoov (TSTshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20150,12 +20150,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftRLreg x y z) yes no)
-+ // result: (LTnoov (TSTshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20173,12 +20173,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TSTshiftRAreg x y z) yes no)
-+ // result: (LTnoov (TSTshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20196,12 +20196,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XOR x y)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQ x y) yes no)
-+ // result: (LTnoov (TEQ x y) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20222,14 +20222,14 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags)
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- break
- }
- // match: (LT (CMPconst [0] l:(XORconst [c] x)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQconst [c] x) yes no)
-+ // result: (LTnoov (TEQconst [c] x) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20247,12 +20247,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg(x)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftLL x y [c]) yes no)
-+ // result: (LTnoov (TEQshiftLL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20271,12 +20271,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftRL x y [c]) yes no)
-+ // result: (LTnoov (TEQshiftRL x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20295,12 +20295,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftRA x y [c]) yes no)
-+ // result: (LTnoov (TEQshiftRA x y [c]) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20319,12 +20319,12 @@ func rewriteBlockARM(b *Block) bool {
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags)
- v0.AuxInt = c
- v0.AddArg2(x, y)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftLLreg x y z) yes no)
-+ // result: (LTnoov (TEQshiftLLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20342,12 +20342,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftRLreg x y z) yes no)
-+ // result: (LTnoov (TEQshiftRLreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20365,12 +20365,12 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- // match: (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
- // cond: l.Uses==1
-- // result: (LT (TEQshiftRAreg x y z) yes no)
-+ // result: (LTnoov (TEQshiftRAreg x y z) yes no)
- for b.Controls[0].Op == OpARMCMPconst {
- v_0 := b.Controls[0]
- if v_0.AuxInt != 0 {
-@@ -20388,7 +20388,7 @@ func rewriteBlockARM(b *Block) bool {
- }
- v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
- v0.AddArg3(x, y, z)
-- b.resetWithControl(BlockARMLT, v0)
-+ b.resetWithControl(BlockARMLTnoov, v0)
- return true
- }
- case BlockARMLTnoov:
-diff --git a/test/fixedbugs/issue42876.go b/test/fixedbugs/issue42876.go
-new file mode 100644
-index 0000000000..67cf4919ac
---- /dev/null
-+++ b/test/fixedbugs/issue42876.go
-@@ -0,0 +1,18 @@
-+// run
-+
-+// 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
-+
-+var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4}
-+
-+func main() {
-+ if x[0] > x[1] {
-+ panic("fail 1")
-+ }
-+ if x[2]&x[3] < 0 {
-+ panic("fail 2") // Fails here
-+ }
-+}
---
-2.29.2
-
diff --git a/go-patches/0014-runtime-make-write-into-function-pointer.patch b/go-patches/0014-runtime-make-write-into-function-pointer.patch
deleted file mode 100644
index 1618f02e..00000000
--- a/go-patches/0014-runtime-make-write-into-function-pointer.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From d7b6f2bfcee5787d9055f5d7ec92c74e258e8fab Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Thu, 3 Dec 2020 13:29:58 +0100
-Subject: [PATCH 14/14] runtime: make write into function pointer
-
-Change-Id: I77a32ff7e1494324e8cc38e792e007f86d32672d
----
- src/runtime/time_nofake.go | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/src/runtime/time_nofake.go b/src/runtime/time_nofake.go
-index 1912a94e87..0564448b2e 100644
---- a/src/runtime/time_nofake.go
-+++ b/src/runtime/time_nofake.go
-@@ -23,9 +23,14 @@ func walltime() (sec int64, nsec int32) {
- return walltime1()
- }
-
-+var overrideWrite func(fd uintptr, p unsafe.Pointer, n int32) int32
-+
- // write must be nosplit on Windows (see write1)
- //
- //go:nosplit
- func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
-+ if overrideWrite != nil {
-+ return overrideWrite(fd, noescape(p), n)
-+ }
- return write1(fd, p, n)
- }
---
-2.29.2
-