[Pkg-golang-commits] [golang] 26/27: Imported Debian patch 2:1.6-0ubuntu2

Michael Hudson-Doyle mwhudson-guest at moszumanska.debian.org
Tue Mar 1 02:57:46 UTC 2016


This is an automated email from the git hooks/post-receive script.

mwhudson-guest pushed a commit to branch gbp
in repository golang.

commit cc375595d4bf6447fd24f363651c5c80e99e1017
Author: Matthias Klose <doko at ubuntu.com>
Date:   Sun Feb 21 16:50:57 2016 +0100

    Imported Debian patch 2:1.6-0ubuntu2
---
 debian/changelog                     |     6 +
 debian/patches/0001-s390x-port.patch | 14009 ++++++++++++++++++++++++++++++---
 2 files changed, 12778 insertions(+), 1237 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 4f7d40d..23d7274 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang (2:1.6-0ubuntu2) xenial; urgency=medium
+
+  * Update d/patches/0001-s390x-port.patch from IBM's repo.
+
+ -- Matthias Klose <doko at ubuntu.com>  Sun, 21 Feb 2016 16:50:57 +0100
+
 golang (2:1.6-0ubuntu1) xenial; urgency=medium
 
   * Go 1.6 release.
diff --git a/debian/patches/0001-s390x-port.patch b/debian/patches/0001-s390x-port.patch
index 4d64ffc..6e8e4b3 100644
--- a/debian/patches/0001-s390x-port.patch
+++ b/debian/patches/0001-s390x-port.patch
@@ -1,204 +1,13 @@
-From 8cafcab0d9460c1fb9c6b05f338f75fb90d00fad Mon Sep 17 00:00:00 2001
-From: wgo <billo at ca.ibm.com>
-Date: Sun, 12 Jul 2015 23:28:19 -0400
 Subject: [PATCH] [s390x] Add support for Linux on IBM z architecture (s390x)
 
-Change-Id: I684a4007d8e4bd2d42cad6ba97b0938031a48458
----
- api/go1.6.txt                                      | 9279 ++++++++++++++++++++
- misc/cgo/test/issue9400/asm_s390x.s                |   31 +
- src/cmd/api/goapi.go                               |    2 +
- src/cmd/asm/internal/arch/arch.go                  |   55 +
- src/cmd/asm/internal/arch/s390x.go                 |  116 +
- src/cmd/asm/internal/asm/asm.go                    |   23 +
- src/cmd/cgo/main.go                                |    2 +-
- src/cmd/cgo/out.go                                 |    1 +
- src/cmd/compile/internal/gc/cgen.go                |   14 +-
- src/cmd/compile/internal/gc/go.go                  |    6 +
- src/cmd/compile/internal/gc/gsubr.go               |    6 +-
- src/cmd/compile/internal/gc/lex.go                 |    8 +-
- src/cmd/compile/internal/gc/pgen.go                |    4 +-
- src/cmd/compile/internal/gc/reg.go                 |    6 +-
- src/cmd/compile/internal/gc/walk.go                |    4 +-
- src/cmd/compile/internal/s390x/cgen.go             |  178 +
- src/cmd/compile/internal/s390x/galign.go           |   95 +
- src/cmd/compile/internal/s390x/ggen.go             |  611 ++
- src/cmd/compile/internal/s390x/gsubr.go            |  972 ++
- src/cmd/compile/internal/s390x/peep.go             | 1419 +++
- src/cmd/compile/internal/s390x/prog.go             |  183 +
- src/cmd/compile/internal/s390x/reg.go              |  131 +
- src/cmd/compile/main.go                            |    3 +
- src/cmd/dist/build.go                              |    1 +
- src/cmd/dist/buildtool.go                          |    3 +
- src/cmd/dist/test.go                               |    4 +-
- src/cmd/dist/util.go                               |    2 +
- src/cmd/go/build.go                                |    8 +-
- src/cmd/internal/obj/link.go                       |    3 +
- src/cmd/internal/obj/s390x/a.out.go                |  360 +
- src/cmd/internal/obj/s390x/anames.go               |  152 +
- src/cmd/internal/obj/s390x/anamesz.go              |   35 +
- src/cmd/internal/obj/s390x/asmz.go                 | 4017 +++++++++
- src/cmd/internal/obj/s390x/listz.go                |   70 +
- src/cmd/internal/obj/s390x/objz.go                 |  990 +++
- src/cmd/internal/obj/util.go                       |    2 +
- src/cmd/internal/objfile/disasm.go                 |    1 +
- src/cmd/internal/objfile/elf.go                    |    2 +
- src/cmd/link/internal/ld/arch.go                   |    9 +
- src/cmd/link/internal/ld/data.go                   |   47 +-
- src/cmd/link/internal/ld/dwarf.go                  |   37 +-
- src/cmd/link/internal/ld/elf.go                    |  120 +-
- src/cmd/link/internal/ld/ldelf.go                  |   45 +-
- src/cmd/link/internal/ld/lib.go                    |    2 +-
- src/cmd/link/internal/ld/link.go                   |    1 +
- src/cmd/link/internal/ld/symtab.go                 |    3 +-
- src/cmd/link/internal/s390x/asm.go                 |  643 ++
- src/cmd/link/internal/s390x/l.go                   |   78 +
- src/cmd/link/internal/s390x/obj.go                 |  115 +
- src/cmd/link/main.go                               |    3 +
- src/cmd/objdump/objdump_test.go                    |    4 +
- src/cmd/vet/asmdecl.go                             |    2 +
- src/crypto/aes/asm_s390x.s                         |   97 +
- src/crypto/aes/cipher_asm.go                       |    2 +-
- src/crypto/aes/cipher_generic.go                   |   10 +-
- src/crypto/aes/gcm_generic.go                      |   15 +
- src/crypto/cipher/xor.go                           |    2 +-
- src/crypto/sha1/sha1block_decl.go                  |    2 +-
- src/crypto/sha1/sha1block_generic.go               |    2 +-
- src/crypto/sha1/sha1block_s390x.s                  |   37 +
- src/crypto/sha256/sha256block.go                   |    2 +-
- src/crypto/sha256/sha256block_decl.go              |    2 +-
- src/crypto/sha256/sha256block_generic.go           |    9 +
- src/crypto/sha256/sha256block_s390x.s              |   37 +
- src/crypto/sha512/sha512block.go                   |    2 +-
- src/crypto/sha512/sha512block_decl.go              |    2 +-
- src/crypto/sha512/sha512block_generic.go           |    9 +
- src/crypto/sha512/sha512block_s390x.s              |   37 +
- src/crypto/x509/sec1.go                            |    8 +-
- src/crypto/x509/sec1_test.go                       |    4 +-
- src/debug/elf/elf.go                               |   66 +
- src/debug/elf/file.go                              |   51 +
- src/debug/gosym/pclntab.go                         |    2 +-
- src/go/build/build.go                              |    1 +
- src/hash/crc32/crc32_generic.go                    |    2 +-
- src/internal/syscall/unix/getrandom_linux_s390x.go |    7 +
- src/math/big/arith_s390x.s                         |  574 ++
- src/math/dim_s390x.s                               |  132 +
- src/math/sqrt_s390x.s                              |   12 +
- src/math/stubs_s390x.s                             |   77 +
- src/net/http/fs_test.go                            |    6 +-
- src/net/lookup_test.go                             |    5 +
- src/reflect/asm_s390x.s                            |   30 +
- src/runtime/asm_s390x.s                            | 1182 +++
- src/runtime/cgo/asm_s390x.s                        |   56 +
- src/runtime/cgo/gcc_linux_s390x.c                  |   68 +
- src/runtime/cgo/gcc_s390x.S                        |   43 +
- src/runtime/cgocall.go                             |    6 +-
- src/runtime/defs_linux_s390x.go                    |  176 +
- src/runtime/extern.go                              |    2 +-
- src/runtime/gcinfo_test.go                         |    2 +-
- src/runtime/hash64.go                              |    2 +-
- src/runtime/internal/atomic/asm_s390x.s            |  192 +
- src/runtime/internal/atomic/atomic_s390x.go        |   63 +
- src/runtime/internal/sys/arch_s390x.go             |   18 +
- src/runtime/internal/sys/zgoarch_s390x.go          |   26 +
- src/runtime/lfstack_linux_s390x.go                 |   25 +
- src/runtime/memclr_s390x.s                         |  122 +
- src/runtime/memmove_s390x.s                        |  189 +
- src/runtime/noasm.go                               |    2 +-
- src/runtime/os1_linux_generic.go                   |    1 +
- src/runtime/os1_linux_s390x.go                     |   29 +
- src/runtime/os2_linux_generic.go                   |    1 +
- src/runtime/os2_linux_s390x.go                     |   22 +
- src/runtime/rt0_linux_s390x.s                      |   20 +
- src/runtime/runtime-gdb_test.go                    |    2 +-
- src/runtime/signal_linux_s390x.go                  |   50 +
- src/runtime/signal_s390x.go                        |  170 +
- src/runtime/sys_linux_s390x.s                      |  437 +
- src/runtime/sys_s390x.go                           |   48 +
- src/runtime/tls_s390x.s                            |   51 +
- src/runtime/unaligned1.go                          |    2 +-
- src/sync/atomic/asm_s390x.s                        |  149 +
- src/syscall/asm_linux_s390x.s                      |  173 +
- src/syscall/exec_linux.go                          |    7 +-
- src/syscall/mkall.sh                               |    7 +
- src/syscall/syscall_linux_s390x.go                 |  296 +
- src/syscall/types_linux.go                         |   18 +
- src/syscall/zerrors_linux_s390x.go                 | 1869 ++++
- src/syscall/zsyscall_linux_s390x.go                | 1578 ++++
- src/syscall/zsysnum_linux_s390x.go                 |  293 +
- src/syscall/ztypes_linux_s390x.go                  |  623 ++
- test/fixedbugs/issue11656.go                       |    2 +
- test/init1.go                                      |    2 +-
- test/nilptr3.go                                    |    3 +-
- test/nosplit.go                                    |    3 +
- 126 files changed, 29072 insertions(+), 110 deletions(-)
- create mode 100644 misc/cgo/test/issue9400/asm_s390x.s
- create mode 100644 src/cmd/asm/internal/arch/s390x.go
- create mode 100644 src/cmd/compile/internal/s390x/cgen.go
- create mode 100644 src/cmd/compile/internal/s390x/galign.go
- create mode 100644 src/cmd/compile/internal/s390x/ggen.go
- create mode 100644 src/cmd/compile/internal/s390x/gsubr.go
- create mode 100644 src/cmd/compile/internal/s390x/peep.go
- create mode 100644 src/cmd/compile/internal/s390x/prog.go
- create mode 100644 src/cmd/compile/internal/s390x/reg.go
- create mode 100644 src/cmd/internal/obj/s390x/a.out.go
- create mode 100644 src/cmd/internal/obj/s390x/anames.go
- create mode 100644 src/cmd/internal/obj/s390x/anamesz.go
- create mode 100644 src/cmd/internal/obj/s390x/asmz.go
- create mode 100644 src/cmd/internal/obj/s390x/listz.go
- create mode 100644 src/cmd/internal/obj/s390x/objz.go
- create mode 100644 src/cmd/link/internal/s390x/asm.go
- create mode 100644 src/cmd/link/internal/s390x/l.go
- create mode 100644 src/cmd/link/internal/s390x/obj.go
- create mode 100644 src/crypto/aes/asm_s390x.s
- create mode 100644 src/crypto/aes/gcm_generic.go
- create mode 100644 src/crypto/sha1/sha1block_s390x.s
- create mode 100644 src/crypto/sha256/sha256block_generic.go
- create mode 100644 src/crypto/sha256/sha256block_s390x.s
- create mode 100644 src/crypto/sha512/sha512block_generic.go
- create mode 100644 src/crypto/sha512/sha512block_s390x.s
- create mode 100644 src/internal/syscall/unix/getrandom_linux_s390x.go
- create mode 100644 src/math/big/arith_s390x.s
- create mode 100644 src/math/dim_s390x.s
- create mode 100644 src/math/sqrt_s390x.s
- create mode 100644 src/math/stubs_s390x.s
- create mode 100644 src/reflect/asm_s390x.s
- create mode 100644 src/runtime/asm_s390x.s
- create mode 100644 src/runtime/cgo/asm_s390x.s
- create mode 100644 src/runtime/cgo/gcc_linux_s390x.c
- create mode 100644 src/runtime/cgo/gcc_s390x.S
- create mode 100644 src/runtime/defs_linux_s390x.go
- create mode 100644 src/runtime/internal/atomic/asm_s390x.s
- create mode 100644 src/runtime/internal/atomic/atomic_s390x.go
- create mode 100644 src/runtime/internal/sys/arch_s390x.go
- create mode 100644 src/runtime/internal/sys/zgoarch_s390x.go
- create mode 100644 src/runtime/lfstack_linux_s390x.go
- create mode 100644 src/runtime/memclr_s390x.s
- create mode 100644 src/runtime/memmove_s390x.s
- create mode 100644 src/runtime/os1_linux_s390x.go
- create mode 100644 src/runtime/os2_linux_s390x.go
- create mode 100644 src/runtime/rt0_linux_s390x.s
- create mode 100644 src/runtime/signal_linux_s390x.go
- create mode 100644 src/runtime/signal_s390x.go
- create mode 100644 src/runtime/sys_linux_s390x.s
- create mode 100644 src/runtime/sys_s390x.go
- create mode 100644 src/runtime/tls_s390x.s
- create mode 100644 src/sync/atomic/asm_s390x.s
- create mode 100644 src/syscall/asm_linux_s390x.s
- create mode 100644 src/syscall/syscall_linux_s390x.go
- create mode 100644 src/syscall/zerrors_linux_s390x.go
- create mode 100644 src/syscall/zsyscall_linux_s390x.go
- create mode 100644 src/syscall/zsysnum_linux_s390x.go
- create mode 100644 src/syscall/ztypes_linux_s390x.go
+https://github.com/linux-on-ibm-z/go/tree/release-branch.go1.6
+git diff bfccf7b3..HEAD
 
-diff --git a/api/go1.6.txt b/api/go1.6.txt
-index d63efd0..6261e9c 100644
---- a/api/go1.6.txt
-+++ b/api/go1.6.txt
-@@ -273,3 +273,9282 @@ pkg text/template, method (ExecError) Error() string
- pkg text/template, type ExecError struct
- pkg text/template, type ExecError struct, Err error
- pkg text/template, type ExecError struct, Name string
+diff --git a/api/next.txt b/api/next.txt
+index e69de29..ec1c52c 100644
+--- a/api/next.txt
++++ b/api/next.txt
+@@ -0,0 +1,9371 @@
 +pkg debug/elf, const R_390_12 = 2
 +pkg debug/elf, const R_390_12 R_S390X
 +pkg debug/elf, const R_390_16 = 3
@@ -465,7 +274,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const AF_LLC ideal-int
 +pkg syscall (linux-s390x-cgo), const AF_LOCAL = 1
 +pkg syscall (linux-s390x-cgo), const AF_LOCAL ideal-int
-+pkg syscall (linux-s390x-cgo), const AF_MAX = 40
++pkg syscall (linux-s390x-cgo), const AF_MAX = 41
 +pkg syscall (linux-s390x-cgo), const AF_MAX ideal-int
 +pkg syscall (linux-s390x-cgo), const AF_NETBEUI = 13
 +pkg syscall (linux-s390x-cgo), const AF_NETBEUI ideal-int
@@ -495,6 +304,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const AF_SNA ideal-int
 +pkg syscall (linux-s390x-cgo), const AF_TIPC = 30
 +pkg syscall (linux-s390x-cgo), const AF_TIPC ideal-int
++pkg syscall (linux-s390x-cgo), const AF_VSOCK = 40
++pkg syscall (linux-s390x-cgo), const AF_VSOCK ideal-int
 +pkg syscall (linux-s390x-cgo), const AF_WANPIPE = 25
 +pkg syscall (linux-s390x-cgo), const AF_WANPIPE ideal-int
 +pkg syscall (linux-s390x-cgo), const AF_X25 = 9
@@ -1059,8 +870,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const EPOLLIN ideal-int
 +pkg syscall (linux-s390x-cgo), const EPOLLMSG = 1024
 +pkg syscall (linux-s390x-cgo), const EPOLLMSG ideal-int
-+pkg syscall (linux-s390x-cgo), const EPOLL_NONBLOCK = 2048
-+pkg syscall (linux-s390x-cgo), const EPOLL_NONBLOCK ideal-int
 +pkg syscall (linux-s390x-cgo), const EPOLLONESHOT = 1073741824
 +pkg syscall (linux-s390x-cgo), const EPOLLONESHOT ideal-int
 +pkg syscall (linux-s390x-cgo), const EPOLLOUT = 4
@@ -1111,8 +920,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const ETH_P_8021AH ideal-int
 +pkg syscall (linux-s390x-cgo), const ETH_P_8021Q = 33024
 +pkg syscall (linux-s390x-cgo), const ETH_P_8021Q ideal-int
-+pkg syscall (linux-s390x-cgo), const ETH_P_80221 = 35095
-+pkg syscall (linux-s390x-cgo), const ETH_P_80221 ideal-int
 +pkg syscall (linux-s390x-cgo), const ETH_P_802_2 = 4
 +pkg syscall (linux-s390x-cgo), const ETH_P_802_2 ideal-int
 +pkg syscall (linux-s390x-cgo), const ETH_P_802_3 = 1
@@ -1373,12 +1180,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IFA_F_DEPRECATED ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_F_HOMEADDRESS = 16
 +pkg syscall (linux-s390x-cgo), const IFA_F_HOMEADDRESS ideal-int
-+pkg syscall (linux-s390x-cgo), const IFA_F_MANAGETEMPADDR = 256
-+pkg syscall (linux-s390x-cgo), const IFA_F_MANAGETEMPADDR ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_F_NODAD = 2
 +pkg syscall (linux-s390x-cgo), const IFA_F_NODAD ideal-int
-+pkg syscall (linux-s390x-cgo), const IFA_F_NOPREFIXROUTE = 512
-+pkg syscall (linux-s390x-cgo), const IFA_F_NOPREFIXROUTE ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_F_OPTIMISTIC = 4
 +pkg syscall (linux-s390x-cgo), const IFA_F_OPTIMISTIC ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_F_PERMANENT = 128
@@ -1393,7 +1196,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IFA_LABEL ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_LOCAL = 2
 +pkg syscall (linux-s390x-cgo), const IFA_LOCAL ideal-int
-+pkg syscall (linux-s390x-cgo), const IFA_MAX = 8
++pkg syscall (linux-s390x-cgo), const IFA_MAX = 7
 +pkg syscall (linux-s390x-cgo), const IFA_MAX ideal-int
 +pkg syscall (linux-s390x-cgo), const IFA_MULTICAST = 7
 +pkg syscall (linux-s390x-cgo), const IFA_MULTICAST ideal-int
@@ -1449,6 +1252,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IFF_MULTI_QUEUE ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_NOARP = 128
 +pkg syscall (linux-s390x-cgo), const IFF_NOARP ideal-int
++pkg syscall (linux-s390x-cgo), const IFF_NOFILTER = 4096
++pkg syscall (linux-s390x-cgo), const IFF_NOFILTER ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_NO_PI = 4096
 +pkg syscall (linux-s390x-cgo), const IFF_NO_PI ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_NOTRAILERS = 32
@@ -1457,6 +1262,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IFF_ONE_QUEUE ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_OVS_DATAPATH = 32768
 +pkg syscall (linux-s390x-cgo), const IFF_OVS_DATAPATH ideal-int
++pkg syscall (linux-s390x-cgo), const IFF_PERSIST = 2048
++pkg syscall (linux-s390x-cgo), const IFF_PERSIST ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_POINTOPOINT = 16
 +pkg syscall (linux-s390x-cgo), const IFF_POINTOPOINT ideal-int
 +pkg syscall (linux-s390x-cgo), const IFF_PORTSEL = 8192
@@ -1693,6 +1500,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IP_PMTUDISC_WANT ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_AH = 51
 +pkg syscall (linux-s390x-cgo), const IPPROTO_AH ideal-int
++pkg syscall (linux-s390x-cgo), const IPPROTO_BEETPH = 94
++pkg syscall (linux-s390x-cgo), const IPPROTO_BEETPH ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_COMP = 108
 +pkg syscall (linux-s390x-cgo), const IPPROTO_COMP ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_DCCP = 33
@@ -1721,6 +1530,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const IPPROTO_IGMP ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_IPIP = 4
 +pkg syscall (linux-s390x-cgo), const IPPROTO_IPIP ideal-int
++pkg syscall (linux-s390x-cgo), const IPPROTO_MH = 135
++pkg syscall (linux-s390x-cgo), const IPPROTO_MH ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_MTP = 92
 +pkg syscall (linux-s390x-cgo), const IPPROTO_MTP ideal-int
 +pkg syscall (linux-s390x-cgo), const IPPROTO_NONE = 59
@@ -1946,8 +1757,10 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const MAP_FIXED ideal-int
 +pkg syscall (linux-s390x-cgo), const MAP_GROWSDOWN = 256
 +pkg syscall (linux-s390x-cgo), const MAP_GROWSDOWN ideal-int
-+pkg syscall (linux-s390x-cgo), const MAP_GROWSUP = 512
-+pkg syscall (linux-s390x-cgo), const MAP_GROWSUP ideal-int
++pkg syscall (linux-s390x-cgo), const MAP_HUGE_MASK = 63
++pkg syscall (linux-s390x-cgo), const MAP_HUGE_MASK ideal-int
++pkg syscall (linux-s390x-cgo), const MAP_HUGE_SHIFT = 26
++pkg syscall (linux-s390x-cgo), const MAP_HUGE_SHIFT ideal-int
 +pkg syscall (linux-s390x-cgo), const MAP_HUGETLB = 262144
 +pkg syscall (linux-s390x-cgo), const MAP_HUGETLB ideal-int
 +pkg syscall (linux-s390x-cgo), const MAP_LOCKED = 8192
@@ -2234,6 +2047,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const O_RSYNC = 1052672
 +pkg syscall (linux-s390x-cgo), const O_RSYNC ideal-int
 +pkg syscall (linux-s390x-cgo), const O_SYNC = 1052672
++pkg syscall (linux-s390x-cgo), const O_TMPFILE = 4259840
++pkg syscall (linux-s390x-cgo), const O_TMPFILE ideal-int
 +pkg syscall (linux-s390x-cgo), const O_TRUNC = 512
 +pkg syscall (linux-s390x-cgo), const PACKET_ADD_MEMBERSHIP = 1
 +pkg syscall (linux-s390x-cgo), const PACKET_ADD_MEMBERSHIP ideal-int
@@ -2389,8 +2204,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const PR_GET_SECCOMP ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_GET_SECUREBITS = 27
 +pkg syscall (linux-s390x-cgo), const PR_GET_SECUREBITS ideal-int
-+pkg syscall (linux-s390x-cgo), const PR_GET_THP_DISABLE = 42
-+pkg syscall (linux-s390x-cgo), const PR_GET_THP_DISABLE ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_GET_TID_ADDRESS = 40
 +pkg syscall (linux-s390x-cgo), const PR_GET_TID_ADDRESS ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_GET_TIMERSLACK = 30
@@ -2487,8 +2300,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const PR_SET_SECCOMP ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_SET_SECUREBITS = 28
 +pkg syscall (linux-s390x-cgo), const PR_SET_SECUREBITS ideal-int
-+pkg syscall (linux-s390x-cgo), const PR_SET_THP_DISABLE = 41
-+pkg syscall (linux-s390x-cgo), const PR_SET_THP_DISABLE ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_SET_TIMERSLACK = 29
 +pkg syscall (linux-s390x-cgo), const PR_SET_TIMERSLACK ideal-int
 +pkg syscall (linux-s390x-cgo), const PR_SET_TIMING = 14
@@ -2665,6 +2476,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const PTRACE_GETREGS ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_GETSIGINFO = 16898
 +pkg syscall (linux-s390x-cgo), const PTRACE_GETSIGINFO ideal-int
++pkg syscall (linux-s390x-cgo), const PTRACE_GETSIGMASK = 16906
++pkg syscall (linux-s390x-cgo), const PTRACE_GETSIGMASK ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_INTERRUPT = 16903
 +pkg syscall (linux-s390x-cgo), const PTRACE_INTERRUPT ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_KILL = 8
@@ -2737,10 +2550,14 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const PTRACE_SETREGS ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_SETSIGINFO = 16899
 +pkg syscall (linux-s390x-cgo), const PTRACE_SETSIGINFO ideal-int
++pkg syscall (linux-s390x-cgo), const PTRACE_SETSIGMASK = 16907
++pkg syscall (linux-s390x-cgo), const PTRACE_SETSIGMASK ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_SINGLESTEP = 9
 +pkg syscall (linux-s390x-cgo), const PTRACE_SINGLESTEP ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_SYSCALL = 24
 +pkg syscall (linux-s390x-cgo), const PTRACE_SYSCALL ideal-int
++pkg syscall (linux-s390x-cgo), const PTRACE_TE_ABORT_RAND = 20497
++pkg syscall (linux-s390x-cgo), const PTRACE_TE_ABORT_RAND ideal-int
 +pkg syscall (linux-s390x-cgo), const PTRACE_TRACEME = 0
 +pkg syscall (linux-s390x-cgo), const PTRACE_TRACEME ideal-int
 +pkg syscall (linux-s390x-cgo), const RLIM_INFINITY = -1
@@ -2811,7 +2628,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const RTAX_INITRWND ideal-int
 +pkg syscall (linux-s390x-cgo), const RTAX_LOCK = 1
 +pkg syscall (linux-s390x-cgo), const RTAX_LOCK ideal-int
-+pkg syscall (linux-s390x-cgo), const RTAX_MAX = 23
++pkg syscall (linux-s390x-cgo), const RTAX_MAX = 15
 +pkg syscall (linux-s390x-cgo), const RTAX_MAX ideal-int
 +pkg syscall (linux-s390x-cgo), const RTAX_MTU = 2
 +pkg syscall (linux-s390x-cgo), const RTAX_MTU ideal-int
@@ -3409,8 +3226,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const SO_ATTACH_FILTER ideal-int
 +pkg syscall (linux-s390x-cgo), const SO_BINDTODEVICE = 25
 +pkg syscall (linux-s390x-cgo), const SO_BINDTODEVICE ideal-int
-+pkg syscall (linux-s390x-cgo), const SO_BPF_EXTENSIONS = 48
-+pkg syscall (linux-s390x-cgo), const SO_BPF_EXTENSIONS ideal-int
 +pkg syscall (linux-s390x-cgo), const SO_BROADCAST = 6
 +pkg syscall (linux-s390x-cgo), const SO_BSDCOMPAT = 14
 +pkg syscall (linux-s390x-cgo), const SO_BSDCOMPAT ideal-int
@@ -4106,10 +3921,24 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const TCOFLUSH ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_CONGESTION = 13
 +pkg syscall (linux-s390x-cgo), const TCP_CONGESTION ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_IN_ALWAYS = 1
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_IN_ALWAYS ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_MAX = 16
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_MAX ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_MIN = 8
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_MIN ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_OUT_NEVER = 2
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_OUT_NEVER ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_PAIR_SIZE = 32
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_PAIR_SIZE ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_TRANSACTIONS = 15
++pkg syscall (linux-s390x-cgo), const TCP_COOKIE_TRANSACTIONS ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_CORK = 3
 +pkg syscall (linux-s390x-cgo), const TCP_CORK ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_DEFER_ACCEPT = 9
 +pkg syscall (linux-s390x-cgo), const TCP_DEFER_ACCEPT ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_FASTOPEN = 23
++pkg syscall (linux-s390x-cgo), const TCP_FASTOPEN ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_INFO = 11
 +pkg syscall (linux-s390x-cgo), const TCP_INFO ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_KEEPCNT = 6
@@ -4131,11 +3960,35 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const TCP_MD5SIG_MAXKEYLEN = 80
 +pkg syscall (linux-s390x-cgo), const TCP_MD5SIG_MAXKEYLEN ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_MSS = 512
++pkg syscall (linux-s390x-cgo), const TCP_MSS_DEFAULT = 536
++pkg syscall (linux-s390x-cgo), const TCP_MSS_DEFAULT ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_MSS_DESIRED = 1220
++pkg syscall (linux-s390x-cgo), const TCP_MSS_DESIRED ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_MSS ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_QUEUE_SEQ = 21
++pkg syscall (linux-s390x-cgo), const TCP_QUEUE_SEQ ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_QUICKACK = 12
 +pkg syscall (linux-s390x-cgo), const TCP_QUICKACK ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR = 19
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR_OPTIONS = 22
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR_OPTIONS ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR_QUEUE = 20
++pkg syscall (linux-s390x-cgo), const TCP_REPAIR_QUEUE ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_S_DATA_IN = 4
++pkg syscall (linux-s390x-cgo), const TCP_S_DATA_IN ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_S_DATA_OUT = 8
++pkg syscall (linux-s390x-cgo), const TCP_S_DATA_OUT ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_SYNCNT = 7
 +pkg syscall (linux-s390x-cgo), const TCP_SYNCNT ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_THIN_DUPACK = 17
++pkg syscall (linux-s390x-cgo), const TCP_THIN_DUPACK ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_THIN_LINEAR_TIMEOUTS = 16
++pkg syscall (linux-s390x-cgo), const TCP_THIN_LINEAR_TIMEOUTS ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_TIMESTAMP = 24
++pkg syscall (linux-s390x-cgo), const TCP_TIMESTAMP ideal-int
++pkg syscall (linux-s390x-cgo), const TCP_USER_TIMEOUT = 18
++pkg syscall (linux-s390x-cgo), const TCP_USER_TIMEOUT ideal-int
 +pkg syscall (linux-s390x-cgo), const TCP_WINDOW_CLAMP = 10
 +pkg syscall (linux-s390x-cgo), const TCP_WINDOW_CLAMP ideal-int
 +pkg syscall (linux-s390x-cgo), const TCSAFLUSH = 2
@@ -4286,6 +4139,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const TUNDETACHFILTER ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNGETFEATURES = 2147767503
 +pkg syscall (linux-s390x-cgo), const TUNGETFEATURES ideal-int
++pkg syscall (linux-s390x-cgo), const TUNGETFILTER = 2148553947
++pkg syscall (linux-s390x-cgo), const TUNGETFILTER ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNGETIFF = 2147767506
 +pkg syscall (linux-s390x-cgo), const TUNGETIFF ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNGETSNDBUF = 2147767507
@@ -4298,6 +4153,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), const TUNSETGROUP ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNSETIFF = 1074025674
 +pkg syscall (linux-s390x-cgo), const TUNSETIFF ideal-int
++pkg syscall (linux-s390x-cgo), const TUNSETIFINDEX = 1074025690
++pkg syscall (linux-s390x-cgo), const TUNSETIFINDEX ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNSETLINK = 1074025677
 +pkg syscall (linux-s390x-cgo), const TUNSETLINK ideal-int
 +pkg syscall (linux-s390x-cgo), const TUNSETNOCSUM = 1074025672
@@ -4574,7 +4431,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), type Cmsghdr struct, Len uint64
 +pkg syscall (linux-s390x-cgo), type Cmsghdr struct, Level int32
 +pkg syscall (linux-s390x-cgo), type Cmsghdr struct, Type int32
-+pkg syscall (linux-s390x-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
 +pkg syscall (linux-s390x-cgo), type Credential struct
 +pkg syscall (linux-s390x-cgo), type Credential struct, Gid uint32
 +pkg syscall (linux-s390x-cgo), type Credential struct, Groups []uint32
@@ -4628,7 +4484,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), type InotifyEvent struct, Cookie uint32
 +pkg syscall (linux-s390x-cgo), type InotifyEvent struct, Len uint32
 +pkg syscall (linux-s390x-cgo), type InotifyEvent struct, Mask uint32
-+pkg syscall (linux-s390x-cgo), type InotifyEvent struct, Name [0]uint8
 +pkg syscall (linux-s390x-cgo), type InotifyEvent struct, Wd int32
 +pkg syscall (linux-s390x-cgo), type Iovec struct
 +pkg syscall (linux-s390x-cgo), type Iovec struct, Base *uint8
@@ -4718,7 +4573,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), type RawSockaddr struct, Family uint16
 +pkg syscall (linux-s390x-cgo), type RawSockaddrUnix struct
 +pkg syscall (linux-s390x-cgo), type RawSockaddrUnix struct, Family uint16
-+pkg syscall (linux-s390x-cgo), type RawSockaddrUnix struct, Path [108]int8
++pkg syscall (linux-s390x-cgo), type RawSockaddrUnix struct, Path [108]uint8
 +pkg syscall (linux-s390x-cgo), type Rlimit struct
 +pkg syscall (linux-s390x-cgo), type Rlimit struct, Cur uint64
 +pkg syscall (linux-s390x-cgo), type Rlimit struct, Max uint64
@@ -4811,7 +4666,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x-cgo), type Stat_t struct, Rdev uint64
 +pkg syscall (linux-s390x-cgo), type Stat_t struct, Size int64
 +pkg syscall (linux-s390x-cgo), type Stat_t struct, Uid uint32
-+pkg syscall (linux-s390x-cgo), type Stat_t struct, X__unused [3]int64
++pkg syscall (linux-s390x-cgo), type Stat_t struct, X__glibc_reserved [3]int64
 +pkg syscall (linux-s390x-cgo), type Sysinfo_t struct
 +pkg syscall (linux-s390x-cgo), type Sysinfo_t struct, Bufferram uint64
 +pkg syscall (linux-s390x-cgo), type Sysinfo_t struct, Freehigh uint64
@@ -4993,7 +4848,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const AF_LLC ideal-int
 +pkg syscall (linux-s390x), const AF_LOCAL = 1
 +pkg syscall (linux-s390x), const AF_LOCAL ideal-int
-+pkg syscall (linux-s390x), const AF_MAX = 40
++pkg syscall (linux-s390x), const AF_MAX = 41
 +pkg syscall (linux-s390x), const AF_MAX ideal-int
 +pkg syscall (linux-s390x), const AF_NETBEUI = 13
 +pkg syscall (linux-s390x), const AF_NETBEUI ideal-int
@@ -5023,6 +4878,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const AF_SNA ideal-int
 +pkg syscall (linux-s390x), const AF_TIPC = 30
 +pkg syscall (linux-s390x), const AF_TIPC ideal-int
++pkg syscall (linux-s390x), const AF_VSOCK = 40
++pkg syscall (linux-s390x), const AF_VSOCK ideal-int
 +pkg syscall (linux-s390x), const AF_WANPIPE = 25
 +pkg syscall (linux-s390x), const AF_WANPIPE ideal-int
 +pkg syscall (linux-s390x), const AF_X25 = 9
@@ -5587,8 +5444,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const EPOLLIN ideal-int
 +pkg syscall (linux-s390x), const EPOLLMSG = 1024
 +pkg syscall (linux-s390x), const EPOLLMSG ideal-int
-+pkg syscall (linux-s390x), const EPOLL_NONBLOCK = 2048
-+pkg syscall (linux-s390x), const EPOLL_NONBLOCK ideal-int
 +pkg syscall (linux-s390x), const EPOLLONESHOT = 1073741824
 +pkg syscall (linux-s390x), const EPOLLONESHOT ideal-int
 +pkg syscall (linux-s390x), const EPOLLOUT = 4
@@ -5639,8 +5494,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const ETH_P_8021AH ideal-int
 +pkg syscall (linux-s390x), const ETH_P_8021Q = 33024
 +pkg syscall (linux-s390x), const ETH_P_8021Q ideal-int
-+pkg syscall (linux-s390x), const ETH_P_80221 = 35095
-+pkg syscall (linux-s390x), const ETH_P_80221 ideal-int
 +pkg syscall (linux-s390x), const ETH_P_802_2 = 4
 +pkg syscall (linux-s390x), const ETH_P_802_2 ideal-int
 +pkg syscall (linux-s390x), const ETH_P_802_3 = 1
@@ -5901,12 +5754,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IFA_F_DEPRECATED ideal-int
 +pkg syscall (linux-s390x), const IFA_F_HOMEADDRESS = 16
 +pkg syscall (linux-s390x), const IFA_F_HOMEADDRESS ideal-int
-+pkg syscall (linux-s390x), const IFA_F_MANAGETEMPADDR = 256
-+pkg syscall (linux-s390x), const IFA_F_MANAGETEMPADDR ideal-int
 +pkg syscall (linux-s390x), const IFA_F_NODAD = 2
 +pkg syscall (linux-s390x), const IFA_F_NODAD ideal-int
-+pkg syscall (linux-s390x), const IFA_F_NOPREFIXROUTE = 512
-+pkg syscall (linux-s390x), const IFA_F_NOPREFIXROUTE ideal-int
 +pkg syscall (linux-s390x), const IFA_F_OPTIMISTIC = 4
 +pkg syscall (linux-s390x), const IFA_F_OPTIMISTIC ideal-int
 +pkg syscall (linux-s390x), const IFA_F_PERMANENT = 128
@@ -5921,7 +5770,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IFA_LABEL ideal-int
 +pkg syscall (linux-s390x), const IFA_LOCAL = 2
 +pkg syscall (linux-s390x), const IFA_LOCAL ideal-int
-+pkg syscall (linux-s390x), const IFA_MAX = 8
++pkg syscall (linux-s390x), const IFA_MAX = 7
 +pkg syscall (linux-s390x), const IFA_MAX ideal-int
 +pkg syscall (linux-s390x), const IFA_MULTICAST = 7
 +pkg syscall (linux-s390x), const IFA_MULTICAST ideal-int
@@ -5977,6 +5826,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IFF_MULTI_QUEUE ideal-int
 +pkg syscall (linux-s390x), const IFF_NOARP = 128
 +pkg syscall (linux-s390x), const IFF_NOARP ideal-int
++pkg syscall (linux-s390x), const IFF_NOFILTER = 4096
++pkg syscall (linux-s390x), const IFF_NOFILTER ideal-int
 +pkg syscall (linux-s390x), const IFF_NO_PI = 4096
 +pkg syscall (linux-s390x), const IFF_NO_PI ideal-int
 +pkg syscall (linux-s390x), const IFF_NOTRAILERS = 32
@@ -5985,6 +5836,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IFF_ONE_QUEUE ideal-int
 +pkg syscall (linux-s390x), const IFF_OVS_DATAPATH = 32768
 +pkg syscall (linux-s390x), const IFF_OVS_DATAPATH ideal-int
++pkg syscall (linux-s390x), const IFF_PERSIST = 2048
++pkg syscall (linux-s390x), const IFF_PERSIST ideal-int
 +pkg syscall (linux-s390x), const IFF_POINTOPOINT = 16
 +pkg syscall (linux-s390x), const IFF_POINTOPOINT ideal-int
 +pkg syscall (linux-s390x), const IFF_PORTSEL = 8192
@@ -6221,6 +6074,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IP_PMTUDISC_WANT ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_AH = 51
 +pkg syscall (linux-s390x), const IPPROTO_AH ideal-int
++pkg syscall (linux-s390x), const IPPROTO_BEETPH = 94
++pkg syscall (linux-s390x), const IPPROTO_BEETPH ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_COMP = 108
 +pkg syscall (linux-s390x), const IPPROTO_COMP ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_DCCP = 33
@@ -6249,6 +6104,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const IPPROTO_IGMP ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_IPIP = 4
 +pkg syscall (linux-s390x), const IPPROTO_IPIP ideal-int
++pkg syscall (linux-s390x), const IPPROTO_MH = 135
++pkg syscall (linux-s390x), const IPPROTO_MH ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_MTP = 92
 +pkg syscall (linux-s390x), const IPPROTO_MTP ideal-int
 +pkg syscall (linux-s390x), const IPPROTO_NONE = 59
@@ -6474,8 +6331,10 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const MAP_FIXED ideal-int
 +pkg syscall (linux-s390x), const MAP_GROWSDOWN = 256
 +pkg syscall (linux-s390x), const MAP_GROWSDOWN ideal-int
-+pkg syscall (linux-s390x), const MAP_GROWSUP = 512
-+pkg syscall (linux-s390x), const MAP_GROWSUP ideal-int
++pkg syscall (linux-s390x), const MAP_HUGE_MASK = 63
++pkg syscall (linux-s390x), const MAP_HUGE_MASK ideal-int
++pkg syscall (linux-s390x), const MAP_HUGE_SHIFT = 26
++pkg syscall (linux-s390x), const MAP_HUGE_SHIFT ideal-int
 +pkg syscall (linux-s390x), const MAP_HUGETLB = 262144
 +pkg syscall (linux-s390x), const MAP_HUGETLB ideal-int
 +pkg syscall (linux-s390x), const MAP_LOCKED = 8192
@@ -6762,6 +6621,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const O_RSYNC = 1052672
 +pkg syscall (linux-s390x), const O_RSYNC ideal-int
 +pkg syscall (linux-s390x), const O_SYNC = 1052672
++pkg syscall (linux-s390x), const O_TMPFILE = 4259840
++pkg syscall (linux-s390x), const O_TMPFILE ideal-int
 +pkg syscall (linux-s390x), const O_TRUNC = 512
 +pkg syscall (linux-s390x), const PACKET_ADD_MEMBERSHIP = 1
 +pkg syscall (linux-s390x), const PACKET_ADD_MEMBERSHIP ideal-int
@@ -6917,8 +6778,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const PR_GET_SECCOMP ideal-int
 +pkg syscall (linux-s390x), const PR_GET_SECUREBITS = 27
 +pkg syscall (linux-s390x), const PR_GET_SECUREBITS ideal-int
-+pkg syscall (linux-s390x), const PR_GET_THP_DISABLE = 42
-+pkg syscall (linux-s390x), const PR_GET_THP_DISABLE ideal-int
 +pkg syscall (linux-s390x), const PR_GET_TID_ADDRESS = 40
 +pkg syscall (linux-s390x), const PR_GET_TID_ADDRESS ideal-int
 +pkg syscall (linux-s390x), const PR_GET_TIMERSLACK = 30
@@ -7015,8 +6874,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const PR_SET_SECCOMP ideal-int
 +pkg syscall (linux-s390x), const PR_SET_SECUREBITS = 28
 +pkg syscall (linux-s390x), const PR_SET_SECUREBITS ideal-int
-+pkg syscall (linux-s390x), const PR_SET_THP_DISABLE = 41
-+pkg syscall (linux-s390x), const PR_SET_THP_DISABLE ideal-int
 +pkg syscall (linux-s390x), const PR_SET_TIMERSLACK = 29
 +pkg syscall (linux-s390x), const PR_SET_TIMERSLACK ideal-int
 +pkg syscall (linux-s390x), const PR_SET_TIMING = 14
@@ -7193,6 +7050,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const PTRACE_GETREGS ideal-int
 +pkg syscall (linux-s390x), const PTRACE_GETSIGINFO = 16898
 +pkg syscall (linux-s390x), const PTRACE_GETSIGINFO ideal-int
++pkg syscall (linux-s390x), const PTRACE_GETSIGMASK = 16906
++pkg syscall (linux-s390x), const PTRACE_GETSIGMASK ideal-int
 +pkg syscall (linux-s390x), const PTRACE_INTERRUPT = 16903
 +pkg syscall (linux-s390x), const PTRACE_INTERRUPT ideal-int
 +pkg syscall (linux-s390x), const PTRACE_KILL = 8
@@ -7265,10 +7124,14 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const PTRACE_SETREGS ideal-int
 +pkg syscall (linux-s390x), const PTRACE_SETSIGINFO = 16899
 +pkg syscall (linux-s390x), const PTRACE_SETSIGINFO ideal-int
++pkg syscall (linux-s390x), const PTRACE_SETSIGMASK = 16907
++pkg syscall (linux-s390x), const PTRACE_SETSIGMASK ideal-int
 +pkg syscall (linux-s390x), const PTRACE_SINGLESTEP = 9
 +pkg syscall (linux-s390x), const PTRACE_SINGLESTEP ideal-int
 +pkg syscall (linux-s390x), const PTRACE_SYSCALL = 24
 +pkg syscall (linux-s390x), const PTRACE_SYSCALL ideal-int
++pkg syscall (linux-s390x), const PTRACE_TE_ABORT_RAND = 20497
++pkg syscall (linux-s390x), const PTRACE_TE_ABORT_RAND ideal-int
 +pkg syscall (linux-s390x), const PTRACE_TRACEME = 0
 +pkg syscall (linux-s390x), const PTRACE_TRACEME ideal-int
 +pkg syscall (linux-s390x), const RLIM_INFINITY = -1
@@ -7339,7 +7202,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const RTAX_INITRWND ideal-int
 +pkg syscall (linux-s390x), const RTAX_LOCK = 1
 +pkg syscall (linux-s390x), const RTAX_LOCK ideal-int
-+pkg syscall (linux-s390x), const RTAX_MAX = 23
++pkg syscall (linux-s390x), const RTAX_MAX = 15
 +pkg syscall (linux-s390x), const RTAX_MAX ideal-int
 +pkg syscall (linux-s390x), const RTAX_MTU = 2
 +pkg syscall (linux-s390x), const RTAX_MTU ideal-int
@@ -7937,8 +7800,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const SO_ATTACH_FILTER ideal-int
 +pkg syscall (linux-s390x), const SO_BINDTODEVICE = 25
 +pkg syscall (linux-s390x), const SO_BINDTODEVICE ideal-int
-+pkg syscall (linux-s390x), const SO_BPF_EXTENSIONS = 48
-+pkg syscall (linux-s390x), const SO_BPF_EXTENSIONS ideal-int
 +pkg syscall (linux-s390x), const SO_BROADCAST = 6
 +pkg syscall (linux-s390x), const SO_BSDCOMPAT = 14
 +pkg syscall (linux-s390x), const SO_BSDCOMPAT ideal-int
@@ -8634,10 +8495,24 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const TCOFLUSH ideal-int
 +pkg syscall (linux-s390x), const TCP_CONGESTION = 13
 +pkg syscall (linux-s390x), const TCP_CONGESTION ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_IN_ALWAYS = 1
++pkg syscall (linux-s390x), const TCP_COOKIE_IN_ALWAYS ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_MAX = 16
++pkg syscall (linux-s390x), const TCP_COOKIE_MAX ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_MIN = 8
++pkg syscall (linux-s390x), const TCP_COOKIE_MIN ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_OUT_NEVER = 2
++pkg syscall (linux-s390x), const TCP_COOKIE_OUT_NEVER ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_PAIR_SIZE = 32
++pkg syscall (linux-s390x), const TCP_COOKIE_PAIR_SIZE ideal-int
++pkg syscall (linux-s390x), const TCP_COOKIE_TRANSACTIONS = 15
++pkg syscall (linux-s390x), const TCP_COOKIE_TRANSACTIONS ideal-int
 +pkg syscall (linux-s390x), const TCP_CORK = 3
 +pkg syscall (linux-s390x), const TCP_CORK ideal-int
 +pkg syscall (linux-s390x), const TCP_DEFER_ACCEPT = 9
 +pkg syscall (linux-s390x), const TCP_DEFER_ACCEPT ideal-int
++pkg syscall (linux-s390x), const TCP_FASTOPEN = 23
++pkg syscall (linux-s390x), const TCP_FASTOPEN ideal-int
 +pkg syscall (linux-s390x), const TCP_INFO = 11
 +pkg syscall (linux-s390x), const TCP_INFO ideal-int
 +pkg syscall (linux-s390x), const TCP_KEEPCNT = 6
@@ -8659,11 +8534,35 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const TCP_MD5SIG_MAXKEYLEN = 80
 +pkg syscall (linux-s390x), const TCP_MD5SIG_MAXKEYLEN ideal-int
 +pkg syscall (linux-s390x), const TCP_MSS = 512
++pkg syscall (linux-s390x), const TCP_MSS_DEFAULT = 536
++pkg syscall (linux-s390x), const TCP_MSS_DEFAULT ideal-int
++pkg syscall (linux-s390x), const TCP_MSS_DESIRED = 1220
++pkg syscall (linux-s390x), const TCP_MSS_DESIRED ideal-int
 +pkg syscall (linux-s390x), const TCP_MSS ideal-int
++pkg syscall (linux-s390x), const TCP_QUEUE_SEQ = 21
++pkg syscall (linux-s390x), const TCP_QUEUE_SEQ ideal-int
 +pkg syscall (linux-s390x), const TCP_QUICKACK = 12
 +pkg syscall (linux-s390x), const TCP_QUICKACK ideal-int
++pkg syscall (linux-s390x), const TCP_REPAIR = 19
++pkg syscall (linux-s390x), const TCP_REPAIR ideal-int
++pkg syscall (linux-s390x), const TCP_REPAIR_OPTIONS = 22
++pkg syscall (linux-s390x), const TCP_REPAIR_OPTIONS ideal-int
++pkg syscall (linux-s390x), const TCP_REPAIR_QUEUE = 20
++pkg syscall (linux-s390x), const TCP_REPAIR_QUEUE ideal-int
++pkg syscall (linux-s390x), const TCP_S_DATA_IN = 4
++pkg syscall (linux-s390x), const TCP_S_DATA_IN ideal-int
++pkg syscall (linux-s390x), const TCP_S_DATA_OUT = 8
++pkg syscall (linux-s390x), const TCP_S_DATA_OUT ideal-int
 +pkg syscall (linux-s390x), const TCP_SYNCNT = 7
 +pkg syscall (linux-s390x), const TCP_SYNCNT ideal-int
++pkg syscall (linux-s390x), const TCP_THIN_DUPACK = 17
++pkg syscall (linux-s390x), const TCP_THIN_DUPACK ideal-int
++pkg syscall (linux-s390x), const TCP_THIN_LINEAR_TIMEOUTS = 16
++pkg syscall (linux-s390x), const TCP_THIN_LINEAR_TIMEOUTS ideal-int
++pkg syscall (linux-s390x), const TCP_TIMESTAMP = 24
++pkg syscall (linux-s390x), const TCP_TIMESTAMP ideal-int
++pkg syscall (linux-s390x), const TCP_USER_TIMEOUT = 18
++pkg syscall (linux-s390x), const TCP_USER_TIMEOUT ideal-int
 +pkg syscall (linux-s390x), const TCP_WINDOW_CLAMP = 10
 +pkg syscall (linux-s390x), const TCP_WINDOW_CLAMP ideal-int
 +pkg syscall (linux-s390x), const TCSAFLUSH = 2
@@ -8814,6 +8713,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const TUNDETACHFILTER ideal-int
 +pkg syscall (linux-s390x), const TUNGETFEATURES = 2147767503
 +pkg syscall (linux-s390x), const TUNGETFEATURES ideal-int
++pkg syscall (linux-s390x), const TUNGETFILTER = 2148553947
++pkg syscall (linux-s390x), const TUNGETFILTER ideal-int
 +pkg syscall (linux-s390x), const TUNGETIFF = 2147767506
 +pkg syscall (linux-s390x), const TUNGETIFF ideal-int
 +pkg syscall (linux-s390x), const TUNGETSNDBUF = 2147767507
@@ -8826,6 +8727,8 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), const TUNSETGROUP ideal-int
 +pkg syscall (linux-s390x), const TUNSETIFF = 1074025674
 +pkg syscall (linux-s390x), const TUNSETIFF ideal-int
++pkg syscall (linux-s390x), const TUNSETIFINDEX = 1074025690
++pkg syscall (linux-s390x), const TUNSETIFINDEX ideal-int
 +pkg syscall (linux-s390x), const TUNSETLINK = 1074025677
 +pkg syscall (linux-s390x), const TUNSETLINK ideal-int
 +pkg syscall (linux-s390x), const TUNSETNOCSUM = 1074025672
@@ -9102,7 +9005,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), type Cmsghdr struct, Len uint64
 +pkg syscall (linux-s390x), type Cmsghdr struct, Level int32
 +pkg syscall (linux-s390x), type Cmsghdr struct, Type int32
-+pkg syscall (linux-s390x), type Cmsghdr struct, X__cmsg_data [0]uint8
 +pkg syscall (linux-s390x), type Credential struct
 +pkg syscall (linux-s390x), type Credential struct, Gid uint32
 +pkg syscall (linux-s390x), type Credential struct, Groups []uint32
@@ -9156,7 +9058,6 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), type InotifyEvent struct, Cookie uint32
 +pkg syscall (linux-s390x), type InotifyEvent struct, Len uint32
 +pkg syscall (linux-s390x), type InotifyEvent struct, Mask uint32
-+pkg syscall (linux-s390x), type InotifyEvent struct, Name [0]uint8
 +pkg syscall (linux-s390x), type InotifyEvent struct, Wd int32
 +pkg syscall (linux-s390x), type Iovec struct
 +pkg syscall (linux-s390x), type Iovec struct, Base *uint8
@@ -9246,7 +9147,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), type RawSockaddr struct, Family uint16
 +pkg syscall (linux-s390x), type RawSockaddrUnix struct
 +pkg syscall (linux-s390x), type RawSockaddrUnix struct, Family uint16
-+pkg syscall (linux-s390x), type RawSockaddrUnix struct, Path [108]int8
++pkg syscall (linux-s390x), type RawSockaddrUnix struct, Path [108]uint8
 +pkg syscall (linux-s390x), type Rlimit struct
 +pkg syscall (linux-s390x), type Rlimit struct, Cur uint64
 +pkg syscall (linux-s390x), type Rlimit struct, Max uint64
@@ -9339,7 +9240,7 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), type Stat_t struct, Rdev uint64
 +pkg syscall (linux-s390x), type Stat_t struct, Size int64
 +pkg syscall (linux-s390x), type Stat_t struct, Uid uint32
-+pkg syscall (linux-s390x), type Stat_t struct, X__unused [3]int64
++pkg syscall (linux-s390x), type Stat_t struct, X__glibc_reserved [3]int64
 +pkg syscall (linux-s390x), type Sysinfo_t struct
 +pkg syscall (linux-s390x), type Sysinfo_t struct, Bufferram uint64
 +pkg syscall (linux-s390x), type Sysinfo_t struct, Freehigh uint64
@@ -9478,12 +9379,31 @@ index d63efd0..6261e9c 100644
 +pkg syscall (linux-s390x), var Stderr int
 +pkg syscall (linux-s390x), var Stdin int
 +pkg syscall (linux-s390x), var Stdout int
+diff --git a/misc/cgo/test/issue13930.go b/misc/cgo/test/issue13930.go
+new file mode 100644
+index 0000000..3a22459
+--- /dev/null
++++ b/misc/cgo/test/issue13930.go
+@@ -0,0 +1,13 @@
++// Copyright 2016 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Issue 13930.  Test that cgo's multiple-value special form for
++// C function calls works in variable declaration statements.
++
++package cgotest
++
++// #include <stdlib.h>
++import "C"
++
++var _, _ = C.abs(0)
 diff --git a/misc/cgo/test/issue9400/asm_s390x.s b/misc/cgo/test/issue9400/asm_s390x.s
 new file mode 100644
-index 0000000..ffe260a
+index 0000000..6330cdf
 --- /dev/null
 +++ b/misc/cgo/test/issue9400/asm_s390x.s
-@@ -0,0 +1,31 @@
+@@ -0,0 +1,26 @@
 +// Copyright 2016 The Go Authors.  All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -9495,26 +9415,35 @@ index 0000000..ffe260a
 +TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0
 +	// Rewind stack pointer so anything that happens on the stack
 +	// will clobber the test pattern created by the caller
-+	// TODO(mundaym): Code generator should support ADD $(1024 * 8), R15
-+	MOVD	$(1024 * 8), R4
-+	ADD	R4, R15
++	ADD	$(1024 * 8), R15
 +
 +	// Ask signaller to setgid
-+	// TODO(mundaym): Code generator should support MOVW $1, ·Baton(SB)
 +	MOVD	$·Baton(SB), R5
-+	MOVW	$1, R6
-+	MOVW	R6, 0(R5)
++	MOVW	$1, 0(R5)
 +
 +	// Wait for setgid completion
 +loop:
 +	SYNC
 +	MOVW	·Baton(SB), R3
-+	CMP	R3, $0
-+	BNE	loop
++	CMPBNE	R3, $0, loop
 +
 +	// Restore stack
-+	SUB	R4, R15
++	SUB	$(1024 * 8), R15
 +	RET
+diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto
+index 4e82ac9..dcb1563 100644
+--- a/misc/nacl/testzip.proto
++++ b/misc/nacl/testzip.proto
+@@ -44,6 +44,9 @@ go	src=..
+ 				gofmt_test.go
+ 				testdata
+ 					+
++			newlink
++				testdata
++					+
+ 		archive
+ 			tar
+ 				testdata
 diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
 index 8b20d12..373e71e 100644
 --- a/src/cmd/api/goapi.go
@@ -9529,7 +9458,7 @@ index 8b20d12..373e71e 100644
  	{GOOS: "darwin", GOARCH: "386"},
  	{GOOS: "darwin", GOARCH: "amd64", CgoEnabled: true},
 diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go
-index c14a13c..4cf5fb7 100644
+index c14a13c..51982a2 100644
 --- a/src/cmd/asm/internal/arch/arch.go
 +++ b/src/cmd/asm/internal/arch/arch.go
 @@ -10,6 +10,7 @@ import (
@@ -9551,7 +9480,16 @@ index c14a13c..4cf5fb7 100644
  	}
  	return nil
  }
-@@ -426,3 +431,53 @@ func archMips64() *Arch {
+@@ -162,8 +167,6 @@ func archX86(linkArch *obj.LinkArch) *Arch {
+ 	instructions["MOVDQ2Q"] = x86.AMOVQ
+ 	instructions["MOVNTDQ"] = x86.AMOVNTO
+ 	instructions["MOVOA"] = x86.AMOVO
+-	instructions["PF2ID"] = x86.APF2IL
+-	instructions["PI2FD"] = x86.API2FL
+ 	instructions["PSLLDQ"] = x86.APSLLO
+ 	instructions["PSRLDQ"] = x86.APSRLO
+ 	instructions["PADDD"] = x86.APADDL
+@@ -426,3 +429,56 @@ func archMips64() *Arch {
  		IsJump:         jumpMIPS64,
  	}
  }
@@ -9566,6 +9504,9 @@ index c14a13c..4cf5fb7 100644
 +	for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
 +		register[obj.Rconv(i)] = int16(i)
 +	}
++	for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
++		register[obj.Rconv(i)] = int16(i)
++	}
 +	for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
 +		register[obj.Rconv(i)] = int16(i)
 +	}
@@ -9607,10 +9548,10 @@ index c14a13c..4cf5fb7 100644
 +}
 diff --git a/src/cmd/asm/internal/arch/s390x.go b/src/cmd/asm/internal/arch/s390x.go
 new file mode 100644
-index 0000000..62a8101
+index 0000000..2b32492
 --- /dev/null
 +++ b/src/cmd/asm/internal/arch/s390x.go
-@@ -0,0 +1,116 @@
+@@ -0,0 +1,136 @@
 +// Copyright 2016 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -9700,12 +9641,28 @@ index 0000000..62a8101
 +	return false
 +}
 +
-+// IsS390xStorageAndStorage reports whether the op (as defined by an s390x.A* constant) refers
-+// to an storage-and-storage format instruction such as mvc, clc, xc, oc or nc.
-+func IsS390xStorageAndStorage(op int) bool {
++// IsS390xWithLength reports whether the op (as defined by an s390x.A* constant)
++// refers to an instruction which takes a length as its first argument.
++func IsS390xWithLength(op int) bool {
 +	switch op {
 +	case s390x.AMVC, s390x.ACLC, s390x.AXC, s390x.AOC, s390x.ANC:
 +		return true
++	case s390x.AVLL, s390x.AVSTL:
++		return true
++	}
++	return false
++}
++
++// IsS390xWithIndex reports whether the op (as defined by an s390x.A* constant)
++// refers to an instruction which takes an index as its first argument.
++func IsS390xWithIndex(op int) bool {
++	switch op {
++	case s390x.AVSCEG, s390x.AVSCEF, s390x.AVGEG, s390x.AVGEF:
++		return true
++	case s390x.AVGMG, s390x.AVGMF, s390x.AVGMH, s390x.AVGMB:
++		return true
++	case s390x.AVLEIG, s390x.AVLEIF, s390x.AVLEIH, s390x.AVLEIB:
++		return true
 +	}
 +	return false
 +}
@@ -9724,11 +9681,15 @@ index 0000000..62a8101
 +		if 0 <= n && n <= 15 {
 +			return s390x.REG_R0 + n, true
 +		}
++	case "V":
++		if 0 <= n && n <= 31 {
++			return s390x.REG_V0 + n, true
++		}
 +	}
 +	return 0, false
 +}
 diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go
-index 9827d70..f67e8ee 100644
+index 9827d70..bb0b3aa 100644
 --- a/src/cmd/asm/internal/asm/asm.go
 +++ b/src/cmd/asm/internal/asm/asm.go
 @@ -381,6 +381,20 @@ func (p *Parser) asmJump(op int, cond string, a []obj.Addr) {
@@ -9757,7 +9718,7 @@ index 9827d70..f67e8ee 100644
  				return
  			}
 +		case 'z':
-+			if arch.IsS390xStorageAndStorage(op) {
++			if arch.IsS390xWithLength(op) || arch.IsS390xWithIndex(op) {
 +				prog.From = a[1]
 +				prog.From3 = newAddr(a[0])
 +			} else {
@@ -9768,6 +9729,52 @@ index 9827d70..f67e8ee 100644
  		default:
  			p.errorf("TODO: implement three-operand instructions for this architecture")
  			return
+@@ -628,6 +651,13 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
+ 			prog.To = a[3]
+ 			break
+ 		}
++		if p.arch.Thechar == 'z' {
++			prog.From = a[1]
++			prog.Reg = p.getRegister(prog, op, &a[2])
++			prog.From3 = newAddr(a[0])
++			prog.To = a[3]
++			break
++		}
+ 		p.errorf("can't handle %s instruction with 4 operands", obj.Aconv(op))
+ 		return
+ 	case 5:
+diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
+index c3a24c2..4c5dc9a 100644
+--- a/src/cmd/cgo/ast.go
++++ b/src/cmd/cgo/ast.go
+@@ -447,7 +447,11 @@ func (f *File) walk(x interface{}, context string, visit func(*File, interface{}
+ 	case *ast.ImportSpec:
+ 	case *ast.ValueSpec:
+ 		f.walk(&n.Type, "type", visit)
+-		f.walk(n.Values, "expr", visit)
++		if len(n.Names) == 2 && len(n.Values) == 1 {
++			f.walk(&n.Values[0], "as2", visit)
++		} else {
++			f.walk(n.Values, "expr", visit)
++		}
+ 	case *ast.TypeSpec:
+ 		f.walk(&n.Type, "type", visit)
+ 
+diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
+index bd38a5c..8b4e2bf 100644
+--- a/src/cmd/cgo/doc.go
++++ b/src/cmd/cgo/doc.go
+@@ -148,8 +148,9 @@ assignment context to retrieve both the return value (if any) and the
+ C errno variable as an error (use _ to skip the result value if the
+ function returns void).  For example:
+ 
+-	n, err := C.sqrt(-1)
++	n, err = C.sqrt(-1)
+ 	_, err := C.voidFunc()
++	var n, err = C.sqrt(1)
+ 
+ Calling C function pointers is currently not supported, however you can
+ declare Go variables which hold C function pointers and pass them
 diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
 index 0906ceb..ff82e16 100644
 --- a/src/cmd/cgo/main.go
@@ -9793,36 +9800,303 @@ index ca0ec0a..912c6c6 100644
  
  	// Write second Go output: definitions of _C_xxx.
  	// In a separate file so that the import of "unsafe" does not
+diff --git a/src/cmd/cgo/util.go b/src/cmd/cgo/util.go
+index 3adb8e8..52ca160 100644
+--- a/src/cmd/cgo/util.go
++++ b/src/cmd/cgo/util.go
+@@ -8,6 +8,7 @@ import (
+ 	"bytes"
+ 	"fmt"
+ 	"go/token"
++	"io/ioutil"
+ 	"os"
+ 	"os/exec"
+ )
+@@ -16,6 +17,43 @@ import (
+ // It returns the output to standard output and standard error.
+ // ok indicates whether the command exited successfully.
+ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
++	if i := find(argv, "-xc"); i >= 0 && argv[len(argv)-1] == "-" {
++		// Some compilers have trouble with standard input.
++		// Others have trouble with -xc.
++		// Avoid both problems by writing a file with a .c extension.
++		f, err := ioutil.TempFile("", "cgo-gcc-input-")
++		if err != nil {
++			fatalf("%s", err)
++		}
++		name := f.Name()
++		f.Close()
++		if err := ioutil.WriteFile(name+".c", stdin, 0666); err != nil {
++			os.Remove(name)
++			fatalf("%s", err)
++		}
++		defer os.Remove(name)
++		defer os.Remove(name + ".c")
++
++		// Build new argument list without -xc and trailing -.
++		new := append(argv[:i:i], argv[i+1:len(argv)-1]...)
++
++		// Since we are going to write the file to a temporary directory,
++		// we will need to add -I . explicitly to the command line:
++		// any #include "foo" before would have looked in the current
++		// directory as the directory "holding" standard input, but now
++		// the temporary directory holds the input.
++		// We've also run into compilers that reject "-I." but allow "-I", ".",
++		// so be sure to use two arguments.
++		// This matters mainly for people invoking cgo -godefs by hand.
++		new = append(new, "-I", ".")
++
++		// Finish argument list with path to C file.
++		new = append(new, name+".c")
++
++		argv = new
++		stdin = nil
++	}
++
+ 	p := exec.Command(argv[0], argv[1:]...)
+ 	p.Stdin = bytes.NewReader(stdin)
+ 	var bout, berr bytes.Buffer
+@@ -30,6 +68,15 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
+ 	return
+ }
+ 
++func find(argv []string, target string) int {
++	for i, arg := range argv {
++		if arg == target {
++			return i
++		}
++	}
++	return -1
++}
++
+ func lineno(pos token.Pos) string {
+ 	return fset.Position(pos).String()
+ }
+diff --git a/src/cmd/compile/internal/big/ratconv.go b/src/cmd/compile/internal/big/ratconv.go
+index 4566ff4..57df124 100644
+--- a/src/cmd/compile/internal/big/ratconv.go
++++ b/src/cmd/compile/internal/big/ratconv.go
+@@ -15,7 +15,7 @@ import (
+ )
+ 
+ func ratTok(ch rune) bool {
+-	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
++	return strings.ContainsRune("+-/0123456789.eE", ch)
+ }
+ 
+ // Scan is a support routine for fmt.Scanner. It accepts the formats
+@@ -25,7 +25,7 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
+ 	if err != nil {
+ 		return err
+ 	}
+-	if strings.IndexRune("efgEFGv", ch) < 0 {
++	if !strings.ContainsRune("efgEFGv", ch) {
+ 		return errors.New("Rat.Scan: invalid verb")
+ 	}
+ 	if _, ok := z.SetString(string(tok)); !ok {
+diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
+index b49f0fb..3edd048 100644
+--- a/src/cmd/compile/internal/gc/bexport.go
++++ b/src/cmd/compile/internal/gc/bexport.go
+@@ -877,7 +877,7 @@ func (p *exporter) byte(b byte) {
+ // tracef is like fmt.Printf but it rewrites the format string
+ // to take care of indentation.
+ func (p *exporter) tracef(format string, args ...interface{}) {
+-	if strings.IndexAny(format, "<>\n") >= 0 {
++	if strings.ContainsAny(format, "<>\n") {
+ 		var buf bytes.Buffer
+ 		for i := 0; i < len(format); i++ {
+ 			// no need to deal with runes
+diff --git a/src/cmd/compile/internal/gc/builtin.go b/src/cmd/compile/internal/gc/builtin.go
+index 4199fb3..7583e8f 100644
+--- a/src/cmd/compile/internal/gc/builtin.go
++++ b/src/cmd/compile/internal/gc/builtin.go
+@@ -3,7 +3,7 @@
+ package gc
+ 
+ const runtimeimport = "" +
+-	"package runtime\n" +
++	"package runtime safe\n" +
+ 	"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n" +
+ 	"func @\"\".panicindex ()\n" +
+ 	"func @\"\".panicslice ()\n" +
+@@ -44,7 +44,7 @@ const runtimeimport = "" +
+ 	"func @\"\".stringtoslicerune (? *[32]rune, ? string) (? []rune)\n" +
+ 	"func @\"\".stringiter (? string, ? int) (? int)\n" +
+ 	"func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n" +
+-	"func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n" +
++	"func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr \"unsafe-uintptr\") (? int)\n" +
+ 	"func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n" +
+ 	"func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n" +
+ 	"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n" +
+@@ -91,31 +91,31 @@ const runtimeimport = "" +
+ 	"func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
+ 	"func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
+ 	"func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n" +
+-	"func @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
+-	"func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ uintptr, @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
++	"func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ uintptr \"unsafe-uintptr\", @\"\".src·3 any)\n" +
+ 	"func @\"\".typedmemmove (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n" +
+ 	"func @\"\".typedslicecopy (@\"\".typ·2 *byte, @\"\".dst·3 any, @\"\".src·4 any) (? int)\n" +
+ 	"func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n" +
+@@ -131,9 +131,9 @@ const runtimeimport = "" +
+ 	"func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n" +
+ 	"func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".cap·4 int) (@\"\".ary·1 []any)\n" +
+ 	"func @\"\".growslice_n (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int) (@\"\".ary·1 []any)\n" +
+-	"func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr)\n" +
+-	"func @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr)\n" +
+-	"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n" +
++	"func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr \"unsafe-uintptr\") (? bool)\n" +
+ 	"func @\"\".memequal8 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
+ 	"func @\"\".memequal16 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
+ 	"func @\"\".memequal32 (@\"\".x·2 *any, @\"\".y·3 *any) (? bool)\n" +
+@@ -148,14 +148,14 @@ const runtimeimport = "" +
+ 	"func @\"\".int64tofloat64 (? int64) (? float64)\n" +
+ 	"func @\"\".uint64tofloat64 (? uint64) (? float64)\n" +
+ 	"func @\"\".complex128div (@\"\".num·2 complex128, @\"\".den·3 complex128) (@\"\".quo·1 complex128)\n" +
+-	"func @\"\".racefuncenter (? uintptr)\n" +
++	"func @\"\".racefuncenter (? uintptr \"unsafe-uintptr\")\n" +
+ 	"func @\"\".racefuncexit ()\n" +
+-	"func @\"\".raceread (? uintptr)\n" +
+-	"func @\"\".racewrite (? uintptr)\n" +
+-	"func @\"\".racereadrange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
+-	"func @\"\".racewriterange (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
+-	"func @\"\".msanread (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
+-	"func @\"\".msanwrite (@\"\".addr·1 uintptr, @\"\".size·2 uintptr)\n" +
++	"func @\"\".raceread (? uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".racewrite (? uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".racereadrange (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".racewriterange (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".msanread (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
++	"func @\"\".msanwrite (@\"\".addr·1 uintptr \"unsafe-uintptr\", @\"\".size·2 uintptr \"unsafe-uintptr\")\n" +
+ 	"\n" +
+ 	"$$\n"
+ 
+diff --git a/src/cmd/compile/internal/gc/builtin/runtime.go b/src/cmd/compile/internal/gc/builtin/runtime.go
+index a50fc2e..08f925f 100644
+--- a/src/cmd/compile/internal/gc/builtin/runtime.go
++++ b/src/cmd/compile/internal/gc/builtin/runtime.go
+@@ -8,7 +8,7 @@
+ 
+ // +build ignore
+ 
+-package PACKAGE
++package runtime
+ 
+ // emitted by compiler, not referred to by go programs
+ 
+diff --git a/src/cmd/compile/internal/gc/builtin/unsafe.go b/src/cmd/compile/internal/gc/builtin/unsafe.go
+index ce50869..a7fc8aa 100644
+--- a/src/cmd/compile/internal/gc/builtin/unsafe.go
++++ b/src/cmd/compile/internal/gc/builtin/unsafe.go
+@@ -8,7 +8,7 @@
+ 
+ // +build ignore
+ 
+-package PACKAGE
++package unsafe
+ 
+ type Pointer uintptr // not really; filled in by compiler
+ 
+diff --git a/src/cmd/compile/internal/gc/builtin_test.go b/src/cmd/compile/internal/gc/builtin_test.go
+new file mode 100644
+index 0000000..94111e6
+--- /dev/null
++++ b/src/cmd/compile/internal/gc/builtin_test.go
+@@ -0,0 +1,31 @@
++// Copyright 2016 The Go Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package gc_test
++
++import (
++	"bytes"
++	"internal/testenv"
++	"io/ioutil"
++	"os/exec"
++	"testing"
++)
++
++func TestBuiltin(t *testing.T) {
++	testenv.MustHaveGoRun(t)
++
++	old, err := ioutil.ReadFile("builtin.go")
++	if err != nil {
++		t.Fatal(err)
++	}
++
++	new, err := exec.Command("go", "run", "mkbuiltin.go", "-stdout").Output()
++	if err != nil {
++		t.Fatal(err)
++	}
++
++	if !bytes.Equal(old, new) {
++		t.Fatal("builtin.go out of date; run mkbuiltin.go")
++	}
++}
 diff --git a/src/cmd/compile/internal/gc/cgen.go b/src/cmd/compile/internal/gc/cgen.go
-index 6456240..8855bac 100644
+index 6456240..5dc74ae 100644
 --- a/src/cmd/compile/internal/gc/cgen.go
 +++ b/src/cmd/compile/internal/gc/cgen.go
-@@ -252,7 +252,7 @@ func cgen_wb(n, res *Node, wb bool) {
+@@ -247,7 +247,7 @@ func cgen_wb(n, res *Node, wb bool) {
  		return
  	}
  
--	if Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
-+	if Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' || Ctxt.Arch.Thechar == 'z' {
- 		// if both are addressable, move
- 		if n.Addable {
- 			if n.Op == OREGISTER || res.Op == OREGISTER {
-@@ -752,14 +752,14 @@ abop: // asymmetric binary
- 		Regalloc(&n1, nl.Type, res)
- 		Cgen(nl, &n1)
- 
--		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
-+		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' && Ctxt.Arch.Thechar != 'z' { // TODO(rsc): Check opcode for arm
- 			n2 = *nr
- 		} else {
- 			Regalloc(&n2, nr.Type, nil)
- 			Cgen(nr, &n2)
- 		}
- 	} else {
--		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
-+		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' && Ctxt.Arch.Thechar != 'z' { // TODO(rsc): Check opcode for arm
- 			n2 = *nr
- 		} else {
- 			Regalloc(&n2, nr.Type, res)
+-	if (Ctxt.Arch.Thechar == '6' || Ctxt.Arch.Thechar == '8') && n.Addable {
++	if (Ctxt.Arch.Thechar == '6' || Ctxt.Arch.Thechar == '8' || Ctxt.Arch.Thechar == 'z') && n.Addable {
+ 		Thearch.Gmove(n, res)
+ 		return
+ 	}
 @@ -1832,7 +1832,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
  			// but they don't support direct generation of a bool value yet.
  			// We can fix that as we go.
@@ -9841,15 +10115,6 @@ index 6456240..8855bac 100644
  			// no need for a temporary
  			bgenNonZero(n, nil, wantTrue, likely, to)
  			return
-@@ -2026,7 +2026,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
- 		Cgen(nl, &n1)
- 		nl = &n1
- 
--		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '9' {
-+		if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '9' && Ctxt.Arch.Thechar != 'z' {
- 			Thearch.Gins(Thearch.Optoas(OCMP, nr.Type), nl, nr)
- 			bins(nr.Type, res, op, likely, to)
- 			return
 @@ -2640,7 +2640,7 @@ func cgen_div(op Op, nl *Node, nr *Node, res *Node) {
  	// in peep and optoas in order to enable this.
  	// TODO(rsc): ppc64 needs to support the relevant instructions
@@ -9859,11 +10124,82 @@ index 6456240..8855bac 100644
  		goto longdiv
  	}
  	w = int(nl.Type.Width * 8)
+diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
+index ff983e7..ccdb781 100644
+--- a/src/cmd/compile/internal/gc/esc.go
++++ b/src/cmd/compile/internal/gc/esc.go
+@@ -962,7 +962,7 @@ func escassign(e *EscState, dst *Node, src *Node) {
+ 			dst = &e.theSink
+ 		}
+ 
+-	case ODOT: // treat "dst.x  = src" as "dst = src"
++	case ODOT: // treat "dst.x = src" as "dst = src"
+ 		escassign(e, dst.Left, src)
+ 
+ 		return
+@@ -1042,7 +1042,6 @@ func escassign(e *EscState, dst *Node, src *Node) {
+ 		ODOTMETH,
+ 		// treat recv.meth as a value with recv in it, only happens in ODEFER and OPROC
+ 		// iface.method already leaks iface in esccall, no need to put in extra ODOTINTER edge here
+-		ODOTTYPE,
+ 		ODOTTYPE2,
+ 		OSLICE,
+ 		OSLICE3,
+@@ -1052,6 +1051,12 @@ func escassign(e *EscState, dst *Node, src *Node) {
+ 		// Conversions, field access, slice all preserve the input value.
+ 		escassign(e, dst, src.Left)
+ 
++	case ODOTTYPE:
++		if src.Type != nil && !haspointers(src.Type) {
++			break
++		}
++		escassign(e, dst, src.Left)
++
+ 	case OAPPEND:
+ 		// Append returns first argument.
+ 		// Subsequent arguments are already leaked because they are operands to append.
+@@ -1549,9 +1554,9 @@ func escflows(e *EscState, dst *Node, src *Node) {
+ // finding an OADDR just means we're following the upstream of a dereference,
+ // so this address doesn't leak (yet).
+ // If level == 0, it means the /value/ of this node can reach the root of this flood.
+-// so if this node is an OADDR, it's argument should be marked as escaping iff
+-// it's currfn/e->loopdepth are different from the flood's root.
+-// Once an object has been moved to the heap, all of it's upstream should be considered
++// so if this node is an OADDR, its argument should be marked as escaping iff
++// its currfn/e->loopdepth are different from the flood's root.
++// Once an object has been moved to the heap, all of its upstream should be considered
+ // escaping to the global scope.
+ func escflood(e *EscState, dst *Node) {
+ 	switch dst.Op {
 diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
-index 3146cae..d4fec64 100644
+index 3146cae..7c1f257 100644
 --- a/src/cmd/compile/internal/gc/go.go
 +++ b/src/cmd/compile/internal/gc/go.go
-@@ -493,6 +493,12 @@ var debugstr string
+@@ -386,15 +386,14 @@ type Sig struct {
+ }
+ 
+ type Io struct {
+-	infile     string
+-	bin        *obj.Biobuf
+-	cp         string // used for content when bin==nil
+-	last       int
+-	peekc      int
+-	peekc1     int // second peekc for ...
+-	nlsemi     bool
+-	eofnl      bool
+-	importsafe bool
++	infile string
++	bin    *obj.Biobuf
++	cp     string // used for content when bin==nil
++	last   int
++	peekc  int
++	peekc1 int // second peekc for ...
++	nlsemi bool
++	eofnl  bool
+ }
+ 
+ type Dlist struct {
+@@ -493,6 +492,12 @@ var debugstr string
  var Debug_checknil int
  var Debug_typeassert int
  
@@ -9908,9 +10244,18 @@ index 30bf736..4a4d23e 100644
  		}
  		if a.Type != obj.TYPE_MEM {
 diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
-index b9c2735..179ec97 100644
+index b9c2735..266e221 100644
 --- a/src/cmd/compile/internal/gc/lex.go
 +++ b/src/cmd/compile/internal/gc/lex.go
+@@ -2,7 +2,7 @@
+ // Use of this source code is governed by a BSD-style
+ // license that can be found in the LICENSE file.
+ 
+-//go:generate go run mkbuiltin.go runtime unsafe
++//go:generate go run mkbuiltin.go
+ 
+ package gc
+ 
 @@ -178,12 +178,14 @@ func Main() {
  	obj.Flagcount("N", "disable optimizations", &Debug['N'])
  	obj.Flagcount("P", "debug peephole optimizer", &Debug['P'])
@@ -9954,6 +10299,201 @@ index b9c2735..179ec97 100644
  		flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
  	}
  	obj.Flagstr("cpuprofile", "write cpu profile to `file`", &cpuprofile)
+@@ -884,7 +888,6 @@ func cannedimports(file string, cp string) {
+ 	curio.infile = file
+ 	curio.cp = cp
+ 	curio.nlsemi = false
+-	curio.importsafe = false
+ 
+ 	typecheckok = true
+ 	incannedimport = 1
+diff --git a/src/cmd/compile/internal/gc/mkbuiltin.go b/src/cmd/compile/internal/gc/mkbuiltin.go
+index b1e4458..13cde5e 100644
+--- a/src/cmd/compile/internal/gc/mkbuiltin.go
++++ b/src/cmd/compile/internal/gc/mkbuiltin.go
+@@ -4,95 +4,90 @@
+ 
+ // +build ignore
+ 
+-// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go
+-// (passed as arguments on the command line by a go:generate comment).
++// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go.
+ // Run this after changing builtin/runtime.go and builtin/unsafe.go
+ // or after changing the export metadata format in the compiler.
+ // Either way, you need to have a working compiler binary first.
+ package main
+ 
+ import (
+-	"bufio"
++	"bytes"
++	"flag"
+ 	"fmt"
+ 	"io"
++	"io/ioutil"
+ 	"log"
+ 	"os"
+ 	"os/exec"
+-	"strings"
+ )
+ 
++var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
++
+ func main() {
+-	f, err := os.Create("builtin.go")
+-	if err != nil {
+-		log.Fatal(err)
+-	}
+-	defer f.Close()
+-	w := bufio.NewWriter(f)
++	flag.Parse()
+ 
+-	fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
+-	fmt.Fprintln(w, "")
+-	fmt.Fprintln(w, "package gc")
++	var b bytes.Buffer
++	fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
++	fmt.Fprintln(&b, "")
++	fmt.Fprintln(&b, "package gc")
+ 
+-	for _, name := range os.Args[1:] {
+-		mkbuiltin(w, name)
+-	}
++	mkbuiltin(&b, "runtime")
++	mkbuiltin(&b, "unsafe")
+ 
+-	if err := w.Flush(); err != nil {
++	var err error
++	if *stdout {
++		_, err = os.Stdout.Write(b.Bytes())
++	} else {
++		err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666)
++	}
++	if err != nil {
+ 		log.Fatal(err)
+ 	}
+ }
+ 
+-// Compile .go file, import data from .6 file, and write Go string version.
++// Compile .go file, import data from .o file, and write Go string version.
+ func mkbuiltin(w io.Writer, name string) {
+-	if err := exec.Command("go", "tool", "compile", "-A", "builtin/"+name+".go").Run(); err != nil {
++	args := []string{"tool", "compile", "-A"}
++	if name == "runtime" {
++		args = append(args, "-u")
++	}
++	args = append(args, "builtin/"+name+".go")
++
++	if err := exec.Command("go", args...).Run(); err != nil {
+ 		log.Fatal(err)
+ 	}
+ 	obj := name + ".o"
+ 	defer os.Remove(obj)
+ 
+-	r, err := os.Open(obj)
++	b, err := ioutil.ReadFile(obj)
+ 	if err != nil {
+ 		log.Fatal(err)
+ 	}
+-	defer r.Close()
+-	scanner := bufio.NewScanner(r)
+ 
+ 	// Look for $$ that introduces imports.
+-	for scanner.Scan() {
+-		if strings.Contains(scanner.Text(), "$$") {
+-			goto Begin
+-		}
++	i := bytes.Index(b, []byte("\n$$\n"))
++	if i < 0 {
++		log.Fatal("did not find beginning of imports")
+ 	}
+-	log.Fatal("did not find beginning of imports")
+-
+-Begin:
+-	initfunc := fmt.Sprintf("init_%s_function", name)
+-
+-	fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name)
+-
+-	// sys.go claims to be in package PACKAGE to avoid
+-	// conflicts during "go tool compile sys.go".  Rename PACKAGE to $2.
+-	replacer := strings.NewReplacer("PACKAGE", name)
++	i += 4
+ 
+-	// Process imports, stopping at $$ that closes them.
+-	for scanner.Scan() {
+-		p := scanner.Text()
+-		if strings.Contains(p, "$$") {
+-			goto End
+-		}
++	// Look for $$ that closes imports.
++	j := bytes.Index(b[i:], []byte("\n$$\n"))
++	if j < 0 {
++		log.Fatal("did not find end of imports")
++	}
++	j += i + 4
+ 
++	// Process and reformat imports.
++	fmt.Fprintf(w, "\nconst %simport = \"\"", name)
++	for _, p := range bytes.SplitAfter(b[i:j], []byte("\n")) {
+ 		// Chop leading white space.
+-		p = strings.TrimLeft(p, " \t")
+-
+-		// Cut out decl of init_$1_function - it doesn't exist.
+-		if strings.Contains(p, initfunc) {
++		p = bytes.TrimLeft(p, " \t")
++		if len(p) == 0 {
+ 			continue
+ 		}
+ 
+-		fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n")
++		fmt.Fprintf(w, " +\n\t%q", p)
+ 	}
+-	log.Fatal("did not find end of imports")
+-
+-End:
+-	fmt.Fprintf(w, "\t\"$$\\n\"\n")
++	fmt.Fprintf(w, "\n")
+ }
+diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
+index 054cf73..dc6ae72 100644
+--- a/src/cmd/compile/internal/gc/parser.go
++++ b/src/cmd/compile/internal/gc/parser.go
+@@ -67,11 +67,10 @@ func (p *parser) loadsys() {
+ 	importpkg = Runtimepkg
+ 
+ 	if Debug['A'] != 0 {
+-		cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n")
++		cannedimports("runtime.Builtin", "package runtime safe\n\n$$\n\n")
+ 	} else {
+ 		cannedimports("runtime.Builtin", runtimeimport)
+ 	}
+-	curio.importsafe = true
+ 
+ 	p.import_package()
+ 	p.import_there()
+@@ -467,9 +466,10 @@ func (p *parser) import_package() {
+ 		p.import_error()
+ 	}
+ 
++	importsafe := false
+ 	if p.tok == LNAME {
+ 		if p.sym_.Name == "safe" {
+-			curio.importsafe = true
++			importsafe = true
+ 		}
+ 		p.next()
+ 	}
+@@ -484,9 +484,9 @@ func (p *parser) import_package() {
+ 	if incannedimport == 0 {
+ 		importpkg.Direct = true
+ 	}
+-	importpkg.Safe = curio.importsafe
++	importpkg.Safe = importsafe
+ 
+-	if safemode != 0 && !curio.importsafe {
++	if safemode != 0 && !importsafe {
+ 		Yyerror("cannot import unsafe package %q", importpkg.Path)
+ 	}
+ }
 diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
 index ffc0ab9..de153b4 100644
 --- a/src/cmd/compile/internal/gc/pgen.go
@@ -10007,6 +10547,18 @@ index 14dc03b..ae54c26 100644
  			Fatalf("regopt not implemented for from3")
  		}
  
+diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
+index f74bb33..8fd6f85 100644
+--- a/src/cmd/compile/internal/gc/typecheck.go
++++ b/src/cmd/compile/internal/gc/typecheck.go
+@@ -936,7 +936,6 @@ OpSwitch:
+ 			n.Type = n.Right.Type
+ 			n.Right = nil
+ 			if n.Type == nil {
+-				n.Type = nil
+ 				return
+ 			}
+ 		}
 diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
 index e008317..0335138 100644
 --- a/src/cmd/compile/internal/gc/walk.go
@@ -10316,10 +10868,10 @@ index 0000000..a1298a2
 +}
 diff --git a/src/cmd/compile/internal/s390x/ggen.go b/src/cmd/compile/internal/s390x/ggen.go
 new file mode 100644
-index 0000000..756f193
+index 0000000..6e06bef
 --- /dev/null
 +++ b/src/cmd/compile/internal/s390x/ggen.go
-@@ -0,0 +1,611 @@
+@@ -0,0 +1,584 @@
 +// Copyright 2016 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -10855,8 +11407,6 @@ index 0000000..756f193
 +// Called after regopt and peep have run.
 +// Expand CHECKNIL pseudo-op into actual nil pointer check.
 +func expandchecks(firstp *obj.Prog) {
-+	var p1 *obj.Prog
-+	var p2 *obj.Prog
 +	for p := (*obj.Prog)(firstp); p != nil; p = p.Link {
 +		if gc.Debug_checknil != 0 && gc.Ctxt.Debugvlog != 0 {
 +			fmt.Printf("expandchecks: %v\n", p)
@@ -10871,57 +11421,32 @@ index 0000000..756f193
 +			gc.Fatalf("invalid nil check %v\n", p)
 +		}
 +
-+		/*
-+			// check is
-+			//	TD $4, R0, arg (R0 is always zero)
-+			// eqv. to:
-+			// 	tdeq r0, arg
-+			// NOTE: this needs special runtime support to make SIGTRAP recoverable.
-+			reg = p->from.reg;
-+			p->as = ATD;
-+			p->from = p->to = p->from3 = zprog.from;
-+			p->from.type = TYPE_CONST;
-+			p->from.offset = 4;
-+			p->from.reg = 0;
-+			p->reg = REGZERO;
-+			p->to.type = TYPE_REG;
-+			p->to.reg = reg;
-+		*/
 +		// check is
-+		//	CMP arg, $0
-+		//	BNE 2(PC) [likely]
-+		//	MOVD R0, 0(R0)
-+		p1 = gc.Ctxt.NewProg()
++		//	CMPBNE arg, $0, 2(PC) [likely]
++		//	MOVD   R0, 0(R0)
++		p1 := gc.Ctxt.NewProg()
 +
-+		p2 = gc.Ctxt.NewProg()
 +		gc.Clearp(p1)
-+		gc.Clearp(p2)
-+		p1.Link = p2
-+		p2.Link = p.Link
++		p1.Link = p.Link
 +		p.Link = p1
 +		p1.Lineno = p.Lineno
-+		p2.Lineno = p.Lineno
 +		p1.Pc = 9999
-+		p2.Pc = 9999
-+		p.As = s390x.ACMP
-+		p.To.Type = obj.TYPE_CONST
-+		p.To.Offset = 0
-+		p1.As = s390x.ABNE
-+
-+		//p1->from.type = TYPE_CONST;
-+		//p1->from.offset = 1; // likely
-+		p1.To.Type = obj.TYPE_BRANCH
++		p.As = s390x.ACMPBNE
++		p.From3 = new(obj.Addr)
++		p.From3.Type = obj.TYPE_CONST
++		p.From3.Offset = 0
 +
-+		p1.To.Val = p2.Link
++		p.To.Type = obj.TYPE_BRANCH
++		p.To.Val = p1.Link
 +
 +		// crash by write to memory address 0.
-+		p2.As = s390x.AMOVD
++		p1.As = s390x.AMOVD
 +
-+		p2.From.Type = obj.TYPE_REG
-+		p2.From.Reg = s390x.REGZERO
-+		p2.To.Type = obj.TYPE_MEM
-+		p2.To.Reg = s390x.REGZERO
-+		p2.To.Offset = 0
++		p1.From.Type = obj.TYPE_REG
++		p1.From.Reg = s390x.REGZERO
++		p1.To.Type = obj.TYPE_MEM
++		p1.To.Reg = s390x.REGZERO
++		p1.To.Offset = 0
 +	}
 +}
 +
@@ -10933,10 +11458,10 @@ index 0000000..756f193
 +}
 diff --git a/src/cmd/compile/internal/s390x/gsubr.go b/src/cmd/compile/internal/s390x/gsubr.go
 new file mode 100644
-index 0000000..00e2059
+index 0000000..52cd5a2
 --- /dev/null
 +++ b/src/cmd/compile/internal/s390x/gsubr.go
-@@ -0,0 +1,972 @@
+@@ -0,0 +1,1115 @@
 +// Derived from Inferno utils/6c/txt.c
 +// http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.c
 +//
@@ -10978,11 +11503,13 @@ index 0000000..00e2059
 +)
 +
 +var resvd = []int{
-+	s390x.REGZERO,
-+	s390x.REGSP, // reserved for SP
-+	s390x.REGG,
-+	s390x.REGTMP,
-+	s390x.REGTMP2,
++	s390x.REGZERO, // R0
++	s390x.REGTMP,  // R10
++	s390x.REGTMP2, // R11
++	s390x.REGCTXT, // R12
++	s390x.REGG,    // R13
++	s390x.REG_LR,  // R14
++	s390x.REGSP,   // R15
 +}
 +
 +// generate
@@ -11105,11 +11632,11 @@ index 0000000..00e2059
 +		return false
 +	}
 +
-+	if f.Xoffset < 0 || f.Xoffset >= 4096 {
++	if f.Xoffset < 0 || f.Xoffset >= 4096-8 {
 +		return false
 +	}
 +
-+	if t.Xoffset < 0 || t.Xoffset >= 4096 {
++	if t.Xoffset < 0 || t.Xoffset >= 4096-8 {
 +		return false
 +	}
 +
@@ -11185,6 +11712,11 @@ index 0000000..00e2059
 +					goto hard
 +				}
 +			}
++
++			// immediate moves to memory have a 12-bit unsigned displacement
++			if t.Xoffset < 0 || t.Xoffset >= 4096-8 {
++				goto hard
++			}
 +		}
 +	}
 +
@@ -11431,7 +11963,7 @@ index 0000000..00e2059
 +		goto rdst
 +
 +	case gc.TFLOAT64<<16 | gc.TFLOAT32:
-+		a = s390x.AFRSP
++		a = s390x.ALEDBR
 +		goto rdst
 +	}
 +
@@ -11477,16 +12009,18 @@ index 0000000..00e2059
 +// It synthesizes some multiple-instruction sequences
 +// so the front end can stay simpler.
 +func gins(as int, f, t *gc.Node) *obj.Prog {
-+	if as >= obj.A_ARCHSPECIFIC {
-+		if x, ok := intLiteral(f); ok {
-+			ginscon(as, x, t)
-+			return nil // caller must not use
++	if t != nil {
++		if as >= obj.A_ARCHSPECIFIC {
++			if x, ok := intLiteral(f); ok {
++				ginscon(as, x, t)
++				return nil // caller must not use
++			}
 +		}
-+	}
-+	if as == s390x.ACMP || as == s390x.ACMPU {
-+		if x, ok := intLiteral(t); ok {
-+			ginscon2(as, f, x)
-+			return nil // caller must not use
++		if as == s390x.ACMP || as == s390x.ACMPU {
++			if x, ok := intLiteral(t); ok {
++				ginscon2(as, f, x)
++				return nil // caller must not use
++			}
 +		}
 +	}
 +	return rawgins(as, f, t)
@@ -11503,7 +12037,7 @@ index 0000000..00e2059
 +
 +	switch as {
 +	// Bad things the front end has done to us. Crash to find call stack.
-+	case s390x.AAND, s390x.AMULLD:
++	case s390x.AMULLD:
 +		if p.From.Type == obj.TYPE_CONST {
 +			gc.Debug['h'] = 1
 +			gc.Fatalf("bad inst: %v", p)
@@ -11885,36 +12419,170 @@ index 0000000..00e2059
 +	OAddable = 1 << 1
 +)
 +
-+func xgen(n *gc.Node, a *gc.Node, o int) bool {
-+	// TODO(mundaym)
-+	return -1 != 0
-+}
++var clean [20]gc.Node
++
++var cleani int = 0
 +
 +func sudoclean() {
-+	return
++	if clean[cleani-1].Op != gc.OEMPTY {
++		gc.Regfree(&clean[cleani-1])
++	}
++	if clean[cleani-2].Op != gc.OEMPTY {
++		gc.Regfree(&clean[cleani-2])
++	}
++	cleani -= 2
 +}
 +
-+// generate code to compute address of n,
-+// a reference to a (perhaps nested) field inside
-+// an array or struct.
-+// return 0 on failure, 1 on success.
-+// on success, leaves usable address in a.
-+//
-+// caller is responsible for calling sudoclean
-+// after successful sudoaddable,
-+// to release the register used for a.
++/*
++ * generate code to compute address of n,
++ * a reference to a (perhaps nested) field inside
++ * an array or struct.
++ * return 0 on failure, 1 on success.
++ * on success, leaves usable address in a.
++ *
++ * caller is responsible for calling sudoclean
++ * after successful sudoaddable,
++ * to release the register used for a.
++ */
 +func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
-+	// TODO(mundaym)
++	if n.Type == nil {
++		return false
++	}
 +
 +	*a = obj.Addr{}
++
++	switch n.Op {
++	case gc.OLITERAL:
++		if !gc.Isconst(n, gc.CTINT) {
++			return false
++		}
++		v := n.Int()
++		switch as {
++		default:
++			return false
++
++		// operations that can cope with a 32-bit immediate
++		// TODO(mundaym): logical operations can work on high bits
++		case s390x.AADD,
++			s390x.AADDC,
++			s390x.ASUB,
++			s390x.AMULLW,
++			s390x.AAND,
++			s390x.AOR,
++			s390x.AXOR,
++			s390x.ASLD,
++			s390x.ASLW,
++			s390x.ASRAW,
++			s390x.ASRAD,
++			s390x.ASRW,
++			s390x.ASRD,
++			s390x.AMOVB,
++			s390x.AMOVBZ,
++			s390x.AMOVH,
++			s390x.AMOVHZ,
++			s390x.AMOVW,
++			s390x.AMOVWZ,
++			s390x.AMOVD:
++			if int64(int32(v)) != v {
++				return false
++			}
++
++		// for comparisons avoid immediates unless they can
++		// fit into a int8/uint8
++		// this favours combined compare and branch instructions
++		case s390x.ACMP:
++			if int64(int8(v)) != v {
++				return false
++			}
++		case s390x.ACMPU:
++			if int64(uint8(v)) != v {
++				return false
++			}
++		}
++
++		cleani += 2
++		reg := &clean[cleani-1]
++		reg1 := &clean[cleani-2]
++		reg.Op = gc.OEMPTY
++		reg1.Op = gc.OEMPTY
++		gc.Naddr(a, n)
++		return true
++
++	case gc.ODOT,
++		gc.ODOTPTR:
++		cleani += 2
++		reg := &clean[cleani-1]
++		reg1 := &clean[cleani-2]
++		reg.Op = gc.OEMPTY
++		reg1.Op = gc.OEMPTY
++		var nn *gc.Node
++		var oary [10]int64
++		o := gc.Dotoffset(n, oary[:], &nn)
++		if nn == nil {
++			sudoclean()
++			return false
++		}
++
++		if nn.Addable && o == 1 && oary[0] >= 0 {
++			// directly addressable set of DOTs
++			n1 := *nn
++
++			n1.Type = n.Type
++			n1.Xoffset += oary[0]
++			// check that the offset fits into a 12-bit displacement
++			if n1.Xoffset < 0 || n1.Xoffset >= (1<<12)-8 {
++				sudoclean()
++				return false
++			}
++			gc.Naddr(a, &n1)
++			return true
++		}
++
++		gc.Regalloc(reg, gc.Types[gc.Tptr], nil)
++		n1 := *reg
++		n1.Op = gc.OINDREG
++		if oary[0] >= 0 {
++			gc.Agen(nn, reg)
++			n1.Xoffset = oary[0]
++		} else {
++			gc.Cgen(nn, reg)
++			gc.Cgen_checknil(reg)
++			n1.Xoffset = -(oary[0] + 1)
++		}
++
++		for i := 1; i < o; i++ {
++			if oary[i] >= 0 {
++				gc.Fatalf("can't happen")
++			}
++			gins(s390x.AMOVD, &n1, reg)
++			gc.Cgen_checknil(reg)
++			n1.Xoffset = -(oary[i] + 1)
++		}
++
++		a.Type = obj.TYPE_NONE
++		a.Index = obj.TYPE_NONE
++		// check that the offset fits into a 12-bit displacement
++		if n1.Xoffset < 0 || n1.Xoffset >= (1<<12)-8 {
++			tmp := n1
++			tmp.Op = gc.OREGISTER
++			tmp.Type = gc.Types[gc.Tptr]
++			tmp.Xoffset = 0
++			gc.Cgen_checknil(&tmp)
++			ginscon(s390x.AADD, n1.Xoffset, &tmp)
++			n1.Xoffset = 0
++		}
++		gc.Naddr(a, &n1)
++		return true
++	}
++
 +	return false
 +}
 diff --git a/src/cmd/compile/internal/s390x/peep.go b/src/cmd/compile/internal/s390x/peep.go
 new file mode 100644
-index 0000000..c49ebca
+index 0000000..343364a
 --- /dev/null
 +++ b/src/cmd/compile/internal/s390x/peep.go
-@@ -0,0 +1,1419 @@
+@@ -0,0 +1,1819 @@
 +// Derived from Inferno utils/6c/peep.c
 +// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.c
 +//
@@ -11966,14 +12634,21 @@ index 0000000..c49ebca
 +	}
 +	gactive = 0
 +
-+	var p *obj.Prog
++	// promote zero moves to MOVD so that they are more likely to
++	// be optimized in later passes
++	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
++		p := r.Prog
++		if isMove(p) && p.As != s390x.AMOVD && regzer(&p.From) != 0 && isGPR(&p.To) {
++			p.As = s390x.AMOVD
++		}
++	}
 +
 +	// constant propagation
 +	// find MOV $con,R followed by
 +	// another MOV $con,R without
 +	// setting R in the interim
 +	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
-+		p = r.Prog
++		p := r.Prog
 +		switch p.As {
 +		case s390x.AMOVD,
 +			s390x.AMOVW, s390x.AMOVWZ,
@@ -11988,59 +12663,39 @@ index 0000000..c49ebca
 +		}
 +	}
 +
-+	var r *gc.Flow
-+	var t int
-+loop1:
-+	//	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
-+	//		gc.Dumpit("loop1", g.Start, 0)
-+	//	}
-+
-+	t = 0
-+	for r = g.Start; r != nil; r = r.Link {
-+		p = r.Prog
++	for {
++		changed := false
++		for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
++			p := r.Prog
++
++			// TODO(austin) Handle smaller moves.  arm and amd64
++			// distinguish between moves that moves that *must*
++			// sign/zero extend and moves that don't care so they
++			// can eliminate moves that don't care without
++			// breaking moves that do care.  This might let us
++			// simplify or remove the next peep loop, too.
++			if p.As == s390x.AMOVD || p.As == s390x.AFMOVD {
++				if regtyp(&p.To) {
++					// Convert uses to $0 to uses of R0 and
++					// propagate R0
++					if p.As == s390x.AMOVD && regzer(&p.From) != 0 {
++						p.From.Type = obj.TYPE_REG
++						p.From.Reg = s390x.REGZERO
++					}
 +
-+		// TODO(austin) Handle smaller moves.  arm and amd64
-+		// distinguish between moves that moves that *must*
-+		// sign/zero extend and moves that don't care so they
-+		// can eliminate moves that don't care without
-+		// breaking moves that do care.  This might let us
-+		// simplify or remove the next peep loop, too.
-+		if p.As == s390x.AMOVD || p.As == s390x.AFMOVD {
-+			if regtyp(&p.To) {
-+				// Try to eliminate reg->reg moves
-+				if regtyp(&p.From) {
-+					if p.From.Type == p.To.Type {
-+						if copyprop(r) {
++					// Try to eliminate reg->reg moves
++					if isGPR(&p.From) || isFPR(&p.From) {
++						if copyprop(r) || (subprop(r) && copyprop(r)) {
 +							excise(r)
-+							t++
-+						} else if subprop(r) && copyprop(r) {
-+							excise(r)
-+							t++
-+						}
-+					}
-+				}
-+
-+				// Convert uses to $0 to uses of R0 and
-+				// propagate R0
-+				if regzer(&p.From) != 0 {
-+					if p.To.Type == obj.TYPE_REG {
-+						p.From.Type = obj.TYPE_REG
-+						p.From.Reg = s390x.REGZERO
-+						if copyprop(r) {
-+							excise(r)
-+							t++
-+						} else if subprop(r) && copyprop(r) {
-+							excise(r)
-+							t++
++							changed = true
 +						}
 +					}
 +				}
 +			}
 +		}
-+	}
-+
-+	if t != 0 {
-+		goto loop1
++		if !changed {
++			break
++		}
 +	}
 +
 +	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
@@ -12053,12 +12708,11 @@ index 0000000..c49ebca
 +	 */
 +
 +	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
-+
 +		if (gc.Debugmovprop != -1) && (movprop_cnt >= gc.Debugmovprop) {
 +			break
 +		}
 +
-+		p = r.Prog
++		p := r.Prog
 +
 +		switch p.As {
 +		case s390x.AFMOVS,
@@ -12095,7 +12749,6 @@ index 0000000..c49ebca
 +
 +		for ; ; r1 = gc.Uniqs(r1) {
 +			var p1 *obj.Prog
-+			var t int
 +
 +			if r1 == nil || r1 == r0 {
 +				break
@@ -12117,7 +12770,7 @@ index 0000000..c49ebca
 +				p1.From = p0.From
 +				movprop_cnt += 1
 +			} else {
-+				t = copyu(p1, v0, nil)
++				t := copyu(p1, v0, nil)
 +				if gc.Debug['D'] != 0 {
 +					fmt.Printf("try v0 mov prop t=%d\n", t)
 +					fmt.Printf("%v\n", p0)
@@ -12174,10 +12827,8 @@ index 0000000..c49ebca
 +	/*
 +	 * look for MOVB x,R; MOVB R,R (for small MOVs not handled above)
 +	 */
-+	var p1 *obj.Prog
-+	var r1 *gc.Flow
 +	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
-+		p = r.Prog
++		p := r.Prog
 +		switch p.As {
 +		default:
 +			continue
@@ -12193,11 +12844,11 @@ index 0000000..c49ebca
 +			}
 +		}
 +
-+		r1 = r.Link
++		r1 := r.Link
 +		if r1 == nil {
 +			continue
 +		}
-+		p1 = r1.Prog
++		p1 := r1.Prog
 +		if p1.As != p.As {
 +			continue
 +		}
@@ -12210,6 +12861,18 @@ index 0000000..c49ebca
 +		excise(r1)
 +	}
 +
++	// Remove redundant moves/casts
++	fuseMoveChains(g.Start)
++	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
++		gc.Dumpit("fuse move chains", g.Start, 0)
++	}
++
++	// Fuse memory zeroing instructions into XC instructions
++	fuseClear(g.Start)
++	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
++		gc.Dumpit("fuse clears", g.Start, 0)
++	}
++
 +	if gc.Debug['P'] > 1 {
 +		goto ret /* allow following code improvement to be suppressed */
 +	}
@@ -12219,7 +12882,7 @@ index 0000000..c49ebca
 +		// push any load from memory as early as possible
 +		// to give it time to complete before use.
 +		for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
-+			p = r.Prog
++			p := r.Prog
 +			switch p.As {
 +			case s390x.AMOVB,
 +				s390x.AMOVW,
@@ -12246,7 +12909,7 @@ index 0000000..c49ebca
 +			break
 +		}
 +
-+		p = r.Prog
++		p := r.Prog
 +
 +		switch p.As {
 +		case s390x.AADD,
@@ -12309,10 +12972,7 @@ index 0000000..c49ebca
 +
 +		p1 := r1.Prog
 +		switch p1.As {
-+		case s390x.AMOVD,
-+			s390x.AMOVW, s390x.AMOVWZ,
-+			s390x.AMOVH, s390x.AMOVHZ,
-+			s390x.AMOVB, s390x.AMOVBZ:
++		case s390x.AMOVD:
 +			if p1.To.Type != obj.TYPE_REG {
 +				continue
 +			}
@@ -12347,30 +13007,31 @@ index 0000000..c49ebca
 +		if (gc.Debugcnb != -1) && (cnb_cnt >= gc.Debugcnb) {
 +			break
 +		}
-+		p = r.Prog
-+		r1 = gc.Uniqs(r)
++		p := r.Prog
++		r1 := gc.Uniqs(r)
 +		if r1 == nil {
 +			continue
 +		}
-+		p1 = r1.Prog
++		p1 := r1.Prog
 +
++		var ins int16
 +		switch p.As {
 +		case s390x.ACMP:
 +			switch p1.As {
 +			case s390x.ABCL, s390x.ABC:
 +				continue
 +			case s390x.ABEQ:
-+				t = s390x.ACMPBEQ
++				ins = s390x.ACMPBEQ
 +			case s390x.ABGE:
-+				t = s390x.ACMPBGE
++				ins = s390x.ACMPBGE
 +			case s390x.ABGT:
-+				t = s390x.ACMPBGT
++				ins = s390x.ACMPBGT
 +			case s390x.ABLE:
-+				t = s390x.ACMPBLE
++				ins = s390x.ACMPBLE
 +			case s390x.ABLT:
-+				t = s390x.ACMPBLT
++				ins = s390x.ACMPBLT
 +			case s390x.ABNE:
-+				t = s390x.ACMPBNE
++				ins = s390x.ACMPBNE
 +			default:
 +				continue
 +			}
@@ -12380,17 +13041,17 @@ index 0000000..c49ebca
 +			case s390x.ABCL, s390x.ABC:
 +				continue
 +			case s390x.ABEQ:
-+				t = s390x.ACMPUBEQ
++				ins = s390x.ACMPUBEQ
 +			case s390x.ABGE:
-+				t = s390x.ACMPUBGE
++				ins = s390x.ACMPUBGE
 +			case s390x.ABGT:
-+				t = s390x.ACMPUBGT
++				ins = s390x.ACMPUBGT
 +			case s390x.ABLE:
-+				t = s390x.ACMPUBLE
++				ins = s390x.ACMPUBLE
 +			case s390x.ABLT:
-+				t = s390x.ACMPUBLT
++				ins = s390x.ACMPUBLT
 +			case s390x.ABNE:
-+				t = s390x.ACMPUBNE
++				ins = s390x.ACMPUBNE
 +			default:
 +				continue
 +			}
@@ -12411,7 +13072,7 @@ index 0000000..c49ebca
 +		}
 +
 +		if p.To.Type == obj.TYPE_REG {
-+			p1.As = int16(t)
++			p1.As = ins
 +			p1.From = p.From
 +			p1.Reg = p.To.Reg
 +			p1.From3 = nil
@@ -12427,7 +13088,7 @@ index 0000000..c49ebca
 +				}
 +			default:
 +			}
-+			p1.As = int16(t)
++			p1.As = ins
 +			p1.From = p.From
 +			p1.Reg = 0
 +			p1.From3 = new(obj.Addr)
@@ -12447,46 +13108,45 @@ index 0000000..c49ebca
 +		gc.Dumpit("compare and branch", g.Start, 0)
 +	}
 +
++	// Fuse LOAD/STORE instructions into LOAD/STORE MULTIPLE instructions
++	fuseMultiple(g.Start)
++	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
++		gc.Dumpit("pass 7 fuse load/store instructions", g.Start, 0)
++	}
++
 +ret:
 +	gc.Flowend(g)
 +}
 +
 +func conprop(r0 *gc.Flow) {
-+	var p *obj.Prog
-+	var t int
-+
 +	p0 := (*obj.Prog)(r0.Prog)
 +	v0 := (*obj.Addr)(&p0.To)
 +	r := (*gc.Flow)(r0)
++	for {
++		r = gc.Uniqs(r)
++		if r == nil || r == r0 {
++			return
++		}
++		if gc.Uniqp(r) == nil {
++			return
++		}
 +
-+loop:
-+	r = gc.Uniqs(r)
-+	if r == nil || r == r0 {
-+		return
-+	}
-+	if gc.Uniqp(r) == nil {
-+		return
-+	}
-+
-+	p = r.Prog
-+	t = copyu(p, v0, nil)
-+	switch t {
-+	case 0, // miss
-+		1: // use
-+		goto loop
-+
-+	case 2, // rar
-+		4: // use and set
-+		break
-+
-+	case 3: // set
-+		if p.As == p0.As && p.From.Type == p0.From.Type && p.From.Reg == p0.From.Reg && p.From.Node == p0.From.Node &&
-+			p.From.Offset == p0.From.Offset && p.From.Scale == p0.From.Scale && p.From.Index == p0.From.Index {
-+			if p.From.Val == p0.From.Val {
-+				excise(r)
-+				goto loop
++		p := r.Prog
++		t := copyu(p, v0, nil)
++		switch t {
++		case 0, // miss
++			1: // use
++			continue
++		case 3: // set
++			if p.As == p0.As && p.From.Type == p0.From.Type && p.From.Reg == p0.From.Reg && p.From.Node == p0.From.Node &&
++				p.From.Offset == p0.From.Offset && p.From.Scale == p0.From.Scale && p.From.Index == p0.From.Index {
++				if p.From.Val == p0.From.Val {
++					excise(r)
++					continue
++				}
 +			}
 +		}
++		break
 +	}
 +}
 +
@@ -12508,12 +13168,11 @@ index 0000000..c49ebca
 +
 +func pushback(r0 *gc.Flow) {
 +	var r *gc.Flow
-+	var p *obj.Prog
 +
 +	var b *gc.Flow
 +	p0 := (*obj.Prog)(r0.Prog)
 +	for r = gc.Uniqp(r0); r != nil && gc.Uniqs(r) != nil; r = gc.Uniqp(r) {
-+		p = r.Prog
++		p := r.Prog
 +		if p.As != obj.ANOP {
 +			if !regconsttyp(&p.From) || !regtyp(&p.To) {
 +				break
@@ -12553,7 +13212,7 @@ index 0000000..c49ebca
 +	t := obj.Prog(*r0.Prog)
 +	for r = gc.Uniqp(r0); ; r = gc.Uniqp(r) {
 +		p0 = r.Link.Prog
-+		p = r.Prog
++		p := r.Prog
 +		p0.As = p.As
 +		p0.Lineno = p.Lineno
 +		p0.From = p.From
@@ -12619,6 +13278,33 @@ index 0000000..c49ebca
 +	return a.Type == obj.TYPE_REG && s390x.REG_R0 <= a.Reg && a.Reg <= s390x.REG_F15 && a.Reg != s390x.REGZERO
 +}
 +
++// isGPR returns true if a refers to a general purpose register (GPR).
++// R0/REGZERO is treated as a GPR.
++func isGPR(a *obj.Addr) bool {
++	return a.Type == obj.TYPE_REG &&
++		s390x.REG_R0 <= a.Reg &&
++		a.Reg <= s390x.REG_R15
++}
++
++func isFPR(a *obj.Addr) bool {
++	return a.Type == obj.TYPE_REG &&
++		s390x.REG_F0 <= a.Reg &&
++		a.Reg <= s390x.REG_F15
++}
++
++// isIndirectMem returns true if a refers to a memory location addressable by a
++// register and an offset, such as:
++// 	x+8(R1)
++// and
++//	0(R10)
++// It returns false if the address contains an index register such as:
++// 	16(R1)(R2*1)
++func isIndirectMem(a *obj.Addr) bool {
++	return a.Type == obj.TYPE_MEM &&
++		a.Index == 0 &&
++		(a.Name == obj.NAME_NONE || a.Name == obj.NAME_AUTO || a.Name == obj.NAME_PARAM)
++}
++
 +/*
 + * the idea is to substitute
 + * one register for another
@@ -12855,7 +13541,7 @@ index 0000000..c49ebca
 +		fmt.Printf("copyu: can't find %v\n", obj.Aconv(int(p.As)))
 +		return 2
 +
-+	case obj.ANOP, /* read p->from, write p->to */
++	case /* read p->from, write p->to */
 +		s390x.AMOVH,
 +		s390x.AMOVHZ,
 +		s390x.AMOVB,
@@ -12870,7 +13556,7 @@ index 0000000..c49ebca
 +		s390x.ASUBZE,
 +		s390x.AFMOVS,
 +		s390x.AFMOVD,
-+		s390x.AFRSP,
++		s390x.ALEDBR,
 +		s390x.AFNEG,
 +		s390x.ALDEBR,
 +		s390x.ACLFEBR,
@@ -13067,7 +13753,7 @@ index 0000000..c49ebca
 +		}
 +		return 0
 +
-+	case obj.ARET:
++	case obj.ARET, obj.AUNDEF:
 +		if s != nil {
 +			return 0
 +		}
@@ -13123,7 +13809,8 @@ index 0000000..c49ebca
 +		obj.AVARDEF,
 +		obj.AVARKILL,
 +		obj.AVARLIVE,
-+		obj.AUSEFIELD:
++		obj.AUSEFIELD,
++		obj.ANOP:
 +		return 0
 +	}
 +}
@@ -13334,9 +14021,390 @@ index 0000000..c49ebca
 +	}
 +	return false
 +}
++
++func isMove(p *obj.Prog) bool {
++	switch p.As {
++	case s390x.AMOVD,
++		s390x.AMOVW, s390x.AMOVWZ,
++		s390x.AMOVH, s390x.AMOVHZ,
++		s390x.AMOVB, s390x.AMOVBZ,
++		s390x.AFMOVD, s390x.AFMOVS:
++		return true
++	}
++	return false
++}
++
++// fuseMoveChains looks to see if destination register is used
++// again and if not merges the moves.
++//
++// Look for this pattern (sequence of moves):
++// 	MOVB	$17, R1
++// 	MOVBZ	R1, R1
++// Replace with:
++//	MOVBZ	$17, R1
++func fuseMoveChains(r *gc.Flow) {
++	for ; r != nil; r = r.Link {
++		p := r.Prog
++		if !isMove(p) || !isGPR(&p.To) {
++			continue
++		}
++
++		// r is a move with a destination register
++		var move *gc.Flow
++		visited := make(map[*gc.Flow]bool)
++		for rr := gc.Uniqs(r); rr != nil; rr = gc.Uniqs(rr) {
++			if visited[rr] {
++				break
++			} else {
++				visited[rr] = true
++			}
++			if gc.Uniqp(rr) == nil {
++				// branch target: leave alone
++				break
++			}
++			pp := rr.Prog
++			if isMove(pp) && isGPR(&pp.From) && isGPR(&pp.To) && pp.From.Reg == p.To.Reg {
++				move = rr
++				break
++			}
++			if pp.As == obj.ANOP {
++				continue
++			}
++			break
++		}
++
++		// we have a move that reads from our destination reg, check if any future
++		// instructions also read from the reg
++		if move != nil && move.Prog.From.Reg != move.Prog.To.Reg {
++			safe := false
++			visited := make(map[*gc.Flow]bool)
++			children := make([]*gc.Flow, 0)
++			if move.S1 != nil {
++				children = append(children, move.S1)
++			}
++			if move.S2 != nil {
++				children = append(children, move.S2)
++			}
++			if len(children) == 0 {
++				safe = true
++			} else {
++				for len(children) > 0 {
++					rr := children[0]
++					if visited[rr] {
++						children = children[1:]
++						continue
++					} else {
++						visited[rr] = true
++					}
++					pp := rr.Prog
++					t := copyu(pp, &p.To, nil)
++					if t == 0 { // not found
++						if rr.S1 != nil {
++							children = append(children, rr.S1)
++						}
++						if rr.S2 != nil {
++							children = append(children, rr.S2)
++						}
++						children = children[1:]
++						continue
++					}
++					if t == 3 { // set
++						children = children[1:]
++						if len(children) == 0 {
++							safe = true
++						}
++						continue
++					}
++					// t is 1, 2 or 4: use
++					break
++				}
++			}
++			if !safe {
++				move = nil
++			}
++		}
++
++		if move == nil {
++			continue
++		}
++
++		pp := move.Prog
++		execute := false
++		// at this point we have something like:
++		// MOV* anything, reg1
++		// MOV* reg1, reg2
++		// now check if this is a cast that cannot be forward propagated
++		if p.As == pp.As {
++			// if the operations match then we can always propagate
++			execute = true
++		}
++		if !execute && isGPR(&p.From) {
++			switch p.As {
++			case s390x.AMOVD:
++				fallthrough
++			case s390x.AMOVWZ:
++				if pp.As == s390x.AMOVWZ {
++					execute = true
++					break
++				}
++				fallthrough
++			case s390x.AMOVHZ:
++				if pp.As == s390x.AMOVHZ {
++					execute = true
++					break
++				}
++				fallthrough
++			case s390x.AMOVBZ:
++				if pp.As == s390x.AMOVBZ {
++					execute = true
++					break
++				}
++			}
++		}
++		if !execute {
++			if (p.As == s390x.AMOVB || p.As == s390x.AMOVBZ) && (pp.As == s390x.AMOVB || pp.As == s390x.AMOVBZ) {
++				execute = true
++			}
++			if (p.As == s390x.AMOVH || p.As == s390x.AMOVHZ) && (pp.As == s390x.AMOVH || pp.As == s390x.AMOVHZ) {
++				execute = true
++			}
++			if (p.As == s390x.AMOVW || p.As == s390x.AMOVWZ) && (pp.As == s390x.AMOVW || pp.As == s390x.AMOVWZ) {
++				execute = true
++			}
++		}
++
++		if execute {
++			pp.From = p.From
++			excise(r)
++		}
++	}
++	return
++}
++
++// fuseClear merges memory clear operations.
++//
++// Looks for this pattern (sequence of clears):
++// 	MOVD	R0, n(R15)
++// 	MOVD	R0, n+8(R15)
++// 	MOVD	R0, n+16(R15)
++// Replaces with:
++//	CLEAR	$24, n(R15)
++func fuseClear(r *gc.Flow) {
++	var clear *obj.Prog
++	for ; r != nil; r = r.Link {
++		// If there is a branch into the instruction stream then
++		// we can't fuse into previous instructions.
++		if gc.Uniqp(r) == nil {
++			clear = nil
++		}
++
++		p := r.Prog
++		if p.As == obj.ANOP {
++			continue
++		}
++		if p.As == s390x.AXC {
++			if p.From.Reg == p.To.Reg && p.From.Offset == p.To.Offset {
++				// TODO(mundaym): merge clears?
++				p.As = s390x.ACLEAR
++				p.From.Offset = p.From3.Offset
++				p.From3 = nil
++				p.From.Type = obj.TYPE_CONST
++				p.From.Reg = 0
++				clear = p
++			} else {
++				clear = nil
++			}
++			continue
++		}
++
++		// Is our source a constant zero?
++		if regzer(&p.From) == 0 {
++			clear = nil
++			continue
++		}
++
++		// Are we moving to memory?
++		if p.To.Type != obj.TYPE_MEM ||
++			p.To.Index != 0 ||
++			p.To.Offset >= 4096 ||
++			!(p.To.Name == obj.NAME_NONE || p.To.Name == obj.NAME_AUTO || p.To.Name == obj.NAME_PARAM) {
++			clear = nil
++			continue
++		}
++
++		size := int64(0)
++		switch p.As {
++		default:
++			clear = nil
++			continue
++		case s390x.AMOVB, s390x.AMOVBZ:
++			size = 1
++		case s390x.AMOVH, s390x.AMOVHZ:
++			size = 2
++		case s390x.AMOVW, s390x.AMOVWZ:
++			size = 4
++		case s390x.AMOVD:
++			size = 8
++		}
++
++		if clear != nil &&
++			clear.To.Reg == p.To.Reg &&
++			clear.To.Name == p.To.Name &&
++			clear.To.Node == p.To.Node &&
++			clear.To.Sym == p.To.Sym {
++
++			min := clear.To.Offset
++			max := clear.To.Offset + clear.From.Offset
++
++			// previous clear is already clearing this region
++			if min <= p.To.Offset && max >= p.To.Offset+size {
++				excise(r)
++				continue
++			}
++
++			// merge forwards
++			if max == p.To.Offset {
++				clear.From.Offset += size
++				excise(r)
++				continue
++			}
++
++			// merge backwards
++			if min-size == p.To.Offset {
++				clear.From.Offset += size
++				clear.To.Offset -= size
++				excise(r)
++				continue
++			}
++		}
++
++		// transform into clear
++		p.From.Type = obj.TYPE_CONST
++		p.From.Offset = size
++		p.From.Reg = 0
++		p.As = s390x.ACLEAR
++		clear = p
++	}
++}
++
++// fuseMultiple merges memory loads and stores into load multiple and
++// store multiple operations.
++//
++// Looks for this pattern (sequence of loads or stores):
++// 	MOVD	R1, 0(R15)
++//	MOVD	R2, 8(R15)
++//	MOVD	R3, 16(R15)
++// Replaces with:
++//	STMG	R1, R3, 0(R15)
++func fuseMultiple(r *gc.Flow) {
++	var fused *obj.Prog
++	for ; r != nil; r = r.Link {
++		// If there is a branch into the instruction stream then
++		// we can't fuse into previous instructions.
++		if gc.Uniqp(r) == nil {
++			fused = nil
++		}
++
++		p := r.Prog
++
++		isStore := isGPR(&p.From) && isIndirectMem(&p.To)
++		isLoad := isGPR(&p.To) && isIndirectMem(&p.From)
++
++		// are we a candidate?
++		size := int64(0)
++		switch p.As {
++		default:
++			fused = nil
++			continue
++		case obj.ANOP:
++			// skip over nops
++			continue
++		case s390x.AMOVW, s390x.AMOVWZ:
++			size = 4
++			// TODO(mundaym): 32-bit load multiple is currently not supported
++			// as it requires sign/zero extension.
++			if !isStore {
++				fused = nil
++				continue
++			}
++		case s390x.AMOVD:
++			size = 8
++			if !isLoad && !isStore {
++				fused = nil
++				continue
++			}
++		}
++
++		// If we merge two loads/stores with different source/destination Nodes
++		// then we will lose a reference the second Node which means that the
++		// compiler might mark the Node as unused and free its slot on the stack.
++		// TODO(mundaym): allow this by adding a dummy reference to the Node.
++		if fused == nil ||
++			fused.From.Node != p.From.Node ||
++			fused.From.Type != p.From.Type ||
++			fused.To.Node != p.To.Node ||
++			fused.To.Type != p.To.Type {
++			fused = p
++			continue
++		}
++
++		// check two addresses
++		ca := func(a, b *obj.Addr, offset int64) bool {
++			return a.Reg == b.Reg && a.Offset+offset == b.Offset &&
++				a.Sym == b.Sym && a.Name == b.Name
++		}
++
++		switch fused.As {
++		default:
++			fused = p
++		case s390x.AMOVW, s390x.AMOVWZ:
++			if size == 4 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 4) {
++				fused.As = s390x.ASTMY
++				fused.Reg = p.From.Reg
++				excise(r)
++			} else {
++				fused = p
++			}
++		case s390x.AMOVD:
++			if size == 8 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 8) {
++				fused.As = s390x.ASTMG
++				fused.Reg = p.From.Reg
++				excise(r)
++			} else if size == 8 && fused.To.Reg+1 == p.To.Reg && ca(&fused.From, &p.From, 8) {
++				fused.As = s390x.ALMG
++				fused.Reg = fused.To.Reg
++				fused.To.Reg = p.To.Reg
++				excise(r)
++			} else {
++				fused = p
++			}
++		case s390x.ASTMG, s390x.ASTMY:
++			if (fused.As == s390x.ASTMY && size != 4) ||
++				(fused.As == s390x.ASTMG && size != 8) {
++				fused = p
++				continue
++			}
++			offset := size * int64(fused.Reg-fused.From.Reg+1)
++			if fused.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, offset) {
++				fused.Reg = p.From.Reg
++				excise(r)
++			} else {
++				fused = p
++			}
++		case s390x.ALMG:
++			offset := 8 * int64(fused.To.Reg-fused.Reg+1)
++			if size == 8 && fused.To.Reg+1 == p.To.Reg && ca(&fused.From, &p.From, offset) {
++				fused.To.Reg = p.To.Reg
++				excise(r)
++			} else {
++				fused = p
++			}
++		}
++	}
++}
 diff --git a/src/cmd/compile/internal/s390x/prog.go b/src/cmd/compile/internal/s390x/prog.go
 new file mode 100644
-index 0000000..591638c
+index 0000000..00cd22c
 --- /dev/null
 +++ b/src/cmd/compile/internal/s390x/prog.go
 @@ -0,0 +1,183 @@
@@ -13411,7 +14479,7 @@ index 0000000..591638c
 +	s390x.AFDIVS: {Flags: gc.SizeF | gc.LeftRead | gc.RegRead | gc.RightWrite},
 +	s390x.AFCMPU: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead},
 +	s390x.ACEBR:  {Flags: gc.SizeF | gc.LeftRead | gc.RightRead},
-+	s390x.AFRSP:  {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
++	s390x.ALEDBR: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
 +	s390x.ALDEBR: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
 +	s390x.AFSQRT: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite},
 +
@@ -13439,19 +14507,17 @@ index 0000000..591638c
 +	s390x.AMOVH:  {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv},
 +	s390x.AMOVHZ: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv},
 +	s390x.AMOVW:  {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv},
-+
-+	// there is no AMOVWU.
 +	s390x.AMOVWZ: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv},
 +	s390x.AMOVD:  {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move},
 +	s390x.AFMOVS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move | gc.Conv},
 +	s390x.AFMOVD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move},
 +
 +	// Storage operations
-+	s390x.AMVC: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead},
-+	s390x.ACLC: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead},
-+	s390x.AXC:  {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead},
-+	s390x.AOC:  {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead},
-+	s390x.ANC:  {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead},
++	s390x.AMVC: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr},
++	s390x.ACLC: {Flags: gc.LeftRead | gc.LeftAddr | gc.RightRead | gc.RightAddr},
++	s390x.AXC:  {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr},
++	s390x.AOC:  {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr},
++	s390x.ANC:  {Flags: gc.LeftRead | gc.LeftAddr | gc.RightWrite | gc.RightAddr},
 +
 +	// Jumps
 +	s390x.ABR:      {Flags: gc.Jump | gc.Break},
@@ -13475,9 +14541,16 @@ index 0000000..591638c
 +	s390x.ACMPUBGT: {Flags: gc.Cjmp},
 +	s390x.ACMPUBLE: {Flags: gc.Cjmp},
 +
-+	obj.ARET:      {Flags: gc.Break},
-+	obj.ADUFFZERO: {Flags: gc.Call},
-+	obj.ADUFFCOPY: {Flags: gc.Call},
++	// Macros
++	s390x.ACLEAR: {Flags: gc.SizeQ | gc.LeftRead | gc.RightAddr | gc.RightWrite},
++
++	// Load/store multiple
++	s390x.ASTMG: {Flags: gc.SizeQ | gc.LeftRead | gc.RightAddr | gc.RightWrite},
++	s390x.ASTMY: {Flags: gc.SizeL | gc.LeftRead | gc.RightAddr | gc.RightWrite},
++	s390x.ALMG:  {Flags: gc.SizeQ | gc.LeftAddr | gc.LeftRead | gc.RightWrite},
++	s390x.ALMY:  {Flags: gc.SizeL | gc.LeftAddr | gc.LeftRead | gc.RightWrite},
++
++	obj.ARET: {Flags: gc.Break},
 +}
 +
 +func proginfo(p *obj.Prog) {
@@ -13494,16 +14567,10 @@ index 0000000..591638c
 +
 +	if (p.From.Type == obj.TYPE_MEM || p.From.Type == obj.TYPE_ADDR) && p.From.Reg != 0 {
 +		info.Regindex |= RtoB(int(p.From.Reg))
-+		if info.Flags&gc.PostInc != 0 {
-+			info.Regset |= RtoB(int(p.From.Reg))
-+		}
 +	}
 +
 +	if (p.To.Type == obj.TYPE_MEM || p.To.Type == obj.TYPE_ADDR) && p.To.Reg != 0 {
 +		info.Regindex |= RtoB(int(p.To.Reg))
-+		if info.Flags&gc.PostInc != 0 {
-+			info.Regset |= RtoB(int(p.To.Reg))
-+		}
 +	}
 +
 +	if p.From.Type == obj.TYPE_ADDR && p.From.Sym != nil && (info.Flags&gc.LeftRead != 0) {
@@ -13511,16 +14578,17 @@ index 0000000..591638c
 +		info.Flags |= gc.LeftAddr
 +	}
 +
-+	if p.As == obj.ADUFFZERO {
-+		info.Reguse |= 1<<0 | RtoB(s390x.REG_R3)
-+		info.Regset |= RtoB(s390x.REG_R3)
-+	}
-+
-+	if p.As == obj.ADUFFCOPY {
-+		// TODO(austin) Revisit when duffcopy is implemented
-+		info.Reguse |= RtoB(s390x.REG_R3) | RtoB(s390x.REG_R4) | RtoB(s390x.REG_R5)
-+
-+		info.Regset |= RtoB(s390x.REG_R3) | RtoB(s390x.REG_R4)
++	switch p.As {
++	// load multiple sets a range of registers
++	case s390x.ALMG, s390x.ALMY:
++		for r := p.Reg; r <= p.To.Reg; r++ {
++			info.Regset |= RtoB(int(r))
++		}
++	// store multiple reads a range of registers
++	case s390x.ASTMG, s390x.ASTMY:
++		for r := p.From.Reg; r <= p.Reg; r++ {
++			info.Reguse |= RtoB(int(r))
++		}
 +	}
 +}
 diff --git a/src/cmd/compile/internal/s390x/reg.go b/src/cmd/compile/internal/s390x/reg.go
@@ -13681,7 +14749,7 @@ index 3d11f51..66bbf84 100644
  	}
  }
 diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
-index 39a88cc..e8b5862 100644
+index 39a88cc..3cb3028 100644
 --- a/src/cmd/dist/build.go
 +++ b/src/cmd/dist/build.go
 @@ -58,6 +58,7 @@ var okgoarch = []string{
@@ -13692,6 +14760,48 @@ index 39a88cc..e8b5862 100644
  }
  
  // The known operating systems.
+@@ -754,7 +755,7 @@ func matchtag(tag string) bool {
+ 		}
+ 		return !matchtag(tag[1:])
+ 	}
+-	return tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux")
++	return tag == "gc" || tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux")
+ }
+ 
+ // shouldbuild reports whether we should build this file.
+@@ -798,10 +799,15 @@ func shouldbuild(file, dir string) bool {
+ 		if p == "" {
+ 			continue
+ 		}
+-		if strings.Contains(p, "package documentation") {
++		code := p
++		i := strings.Index(code, "//")
++		if i > 0 {
++			code = strings.TrimSpace(code[:i])
++		}
++		if code == "package documentation" {
+ 			return false
+ 		}
+-		if strings.Contains(p, "package main") && dir != "cmd/go" && dir != "cmd/cgo" {
++		if code == "package main" && dir != "cmd/go" && dir != "cmd/cgo" {
+ 			return false
+ 		}
+ 		if !strings.HasPrefix(p, "//") {
+@@ -810,11 +816,11 @@ func shouldbuild(file, dir string) bool {
+ 		if !strings.Contains(p, "+build") {
+ 			continue
+ 		}
+-		fields := splitfields(p)
+-		if len(fields) < 2 || fields[1] != "+build" {
++		fields := splitfields(p[2:])
++		if len(fields) < 1 || fields[0] != "+build" {
+ 			continue
+ 		}
+-		for _, p := range fields[2:] {
++		for _, p := range fields[1:] {
+ 			if matchfield(p) {
+ 				goto fieldmatch
+ 			}
 diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
 index 20d9535..c8ab50e 100644
 --- a/src/cmd/dist/buildtool.go
@@ -13721,7 +14831,7 @@ index 20d9535..c8ab50e 100644
  
  func bootstrapBuildTools() {
 diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
-index 156b868..ef23b34 100644
+index 36c829d..320f10d 100644
 --- a/src/cmd/dist/test.go
 +++ b/src/cmd/dist/test.go
 @@ -667,7 +667,7 @@ func (t *tester) supportedBuildmode(mode string) bool {
@@ -13755,8 +14865,34 @@ index 1b5d1f9..cf8966d 100644
  		case gohostos == "darwin":
  			if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM_") {
  				gohostarch = "arm"
+diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
+index c81bd40..bbad8d4 100644
+--- a/src/cmd/go/alldocs.go
++++ b/src/cmd/go/alldocs.go
+@@ -1022,12 +1022,6 @@ Vendor directories do not affect the placement of new repositories
+ being checked out for the first time by 'go get': those are always
+ placed in the main GOPATH, never in a vendor subtree.
+ 
+-In Go 1.5, as an experiment, setting the environment variable
+-GO15VENDOREXPERIMENT=1 enabled these features.
+-As of Go 1.6 they are on by default. To turn them off, set
+-GO15VENDOREXPERIMENT=0. In Go 1.7, the environment
+-variable will stop having any effect.
+-
+ See https://golang.org/s/go15vendor for details.
+ 
+ 
+@@ -1094,8 +1088,6 @@ Special-purpose environment variables:
+ 		installed in a location other than where it is built.
+ 		File names in stack traces are rewritten from GOROOT to
+ 		GOROOT_FINAL.
+-	GO15VENDOREXPERIMENT
+-		Set to 0 to disable vendoring semantics.
+ 	GO_EXTLINK_ENABLED
+ 		Whether the linker should use external linking mode
+ 		when using -linkmode=auto with code that uses cgo.
 diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
-index a1f925e..fffb40c 100644
+index f2a2a60..af5f2d3 100644
 --- a/src/cmd/go/build.go
 +++ b/src/cmd/go/build.go
 @@ -377,7 +377,7 @@ func buildModeInit() {
@@ -13786,7 +14922,80 @@ index a1f925e..fffb40c 100644
  				buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
  			default:
  				fatalf("-linkshared not supported on %s\n", platform)
-@@ -2958,6 +2958,8 @@ func (b *builder) gccArchArgs() []string {
+@@ -686,6 +686,7 @@ type builder struct {
+ 	work        string               // the temporary work directory (ends in filepath.Separator)
+ 	actionCache map[cacheKey]*action // a cache of already-constructed actions
+ 	mkdirCache  map[string]bool      // a cache of created directories
++	flagCache   map[string]bool      // a cache of supported compiler flags
+ 	print       func(args ...interface{}) (int, error)
+ 
+ 	output    sync.Mutex
+@@ -2927,6 +2928,17 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
+ 	// disable word wrapping in error messages
+ 	a = append(a, "-fmessage-length=0")
+ 
++	// Tell gcc not to include the work directory in object files.
++	if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
++		a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
++	}
++
++	// Tell gcc not to include flags in object files, which defeats the
++	// point of -fdebug-prefix-map above.
++	if b.gccSupportsFlag("-gno-record-gcc-switches") {
++		a = append(a, "-gno-record-gcc-switches")
++	}
++
+ 	// On OS X, some of the compilers behave as if -fno-common
+ 	// is always set, and the Mach-O linker in 6l/8l assumes this.
+ 	// See https://golang.org/issue/3253.
+@@ -2941,19 +2953,24 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
+ // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
+ // not supported by all compilers.
+ func (b *builder) gccSupportsNoPie() bool {
+-	if goos != "linux" {
+-		// On some BSD platforms, error messages from the
+-		// compiler make it to the console despite cmd.Std*
+-		// all being nil. As -no-pie is only required on linux
+-		// systems so far, we only test there.
+-		return false
++	return b.gccSupportsFlag("-no-pie")
++}
++
++// gccSupportsFlag checks to see if the compiler supports a flag.
++func (b *builder) gccSupportsFlag(flag string) bool {
++	b.exec.Lock()
++	defer b.exec.Unlock()
++	if b, ok := b.flagCache[flag]; ok {
++		return b
+ 	}
+-	src := filepath.Join(b.work, "trivial.c")
+-	if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
+-		return false
++	if b.flagCache == nil {
++		src := filepath.Join(b.work, "trivial.c")
++		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
++			return false
++		}
++		b.flagCache = make(map[string]bool)
+ 	}
+-	cmdArgs := b.gccCmd(b.work)
+-	cmdArgs = append(cmdArgs, "-no-pie", "-c", "trivial.c")
++	cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
+ 	if buildN || buildX {
+ 		b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
+ 		if buildN {
+@@ -2964,7 +2981,9 @@ func (b *builder) gccSupportsNoPie() bool {
+ 	cmd.Dir = b.work
+ 	cmd.Env = envForDir(cmd.Dir, os.Environ())
+ 	out, err := cmd.CombinedOutput()
+-	return err == nil && !bytes.Contains(out, []byte("unrecognized"))
++	supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
++	b.flagCache[flag] = supported
++	return supported
+ }
+ 
+ // gccArchArgs returns arguments to pass to gcc based on the architecture.
+@@ -2976,6 +2995,8 @@ func (b *builder) gccArchArgs() []string {
  		return []string{"-m64"}
  	case "arm":
  		return []string{"-marm"} // not thumb
@@ -13795,26 +15004,397 @@ index a1f925e..fffb40c 100644
  	}
  	return nil
  }
-diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
-index 762a49e..465e4d0 100644
---- a/src/cmd/internal/obj/link.go
-+++ b/src/cmd/internal/obj/link.go
-@@ -521,6 +521,9 @@ const (
- 	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the
- 	// relocated symbol rather than the symbol's address.
- 	R_ADDRPOWER_TOCREL_DS
+diff --git a/src/cmd/go/env.go b/src/cmd/go/env.go
+index 24f6127..8d427b3 100644
+--- a/src/cmd/go/env.go
++++ b/src/cmd/go/env.go
+@@ -33,11 +33,6 @@ func mkEnv() []envVar {
+ 	var b builder
+ 	b.init()
+ 
+-	vendorExpValue := "0"
+-	if go15VendorExperiment {
+-		vendorExpValue = "1"
+-	}
+-
+ 	env := []envVar{
+ 		{"GOARCH", goarch},
+ 		{"GOBIN", gobin},
+@@ -49,7 +44,6 @@ func mkEnv() []envVar {
+ 		{"GORACE", os.Getenv("GORACE")},
+ 		{"GOROOT", goroot},
+ 		{"GOTOOLDIR", toolDir},
+-		{"GO15VENDOREXPERIMENT", vendorExpValue},
+ 
+ 		// disable escape codes in clang errors
+ 		{"TERM", "dumb"},
+diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
+index 39e0f3e..ae42608 100644
+--- a/src/cmd/go/go_test.go
++++ b/src/cmd/go/go_test.go
+@@ -1657,8 +1657,8 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
+ 		func main() {
+ 			println(extern)
+ 		}`)
+-	tg.run("run", "-ldflags", `-X main.extern "hello world"`, tg.path("main.go"))
+-	tg.grepStderr("^hello world", `ldflags -X main.extern 'hello world' failed`)
++	tg.run("run", "-ldflags", `-X "main.extern=hello world"`, tg.path("main.go"))
++	tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
+ }
+ 
+ func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
+@@ -1726,7 +1726,6 @@ func TestSymlinksVendor(t *testing.T) {
+ 
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.tempDir("gopath/src/dir1/vendor/v")
+ 	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
+ 	tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
+@@ -2759,3 +2758,30 @@ func TestParallelTest(t *testing.T) {
+ 	tg.setenv("GOPATH", tg.path("."))
+ 	tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
+ }
 +
-+	// R_PCRELDBL is for S390x (z) 2-byte aligned addresses (e.g. R_390_PLT32DBL)
-+	R_PCRELDBL
- )
++func TestCgoConsistentResults(t *testing.T) {
++	if !canCgo {
++		t.Skip("skipping because cgo not enabled")
++	}
++
++	tg := testgo(t)
++	defer tg.cleanup()
++	tg.parallel()
++	tg.makeTempdir()
++	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
++	exe1 := tg.path("cgotest1" + exeSuffix)
++	exe2 := tg.path("cgotest2" + exeSuffix)
++	tg.run("build", "-o", exe1, "cgotest")
++	tg.run("build", "-x", "-o", exe2, "cgotest")
++	b1, err := ioutil.ReadFile(exe1)
++	tg.must(err)
++	b2, err := ioutil.ReadFile(exe2)
++	tg.must(err)
++
++	if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) {
++		t.Skip("skipping because C compiler does not support -fdebug-prefix-map")
++	}
++	if !bytes.Equal(b1, b2) {
++		t.Error("building cgotest twice did not produce the same output")
++	}
++}
+diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
+index d8e7efe..de5e5dd 100644
+--- a/src/cmd/go/help.go
++++ b/src/cmd/go/help.go
+@@ -421,12 +421,6 @@ Vendor directories do not affect the placement of new repositories
+ being checked out for the first time by 'go get': those are always
+ placed in the main GOPATH, never in a vendor subtree.
  
- type Auto struct {
-diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go
-new file mode 100644
-index 0000000..a809306
---- /dev/null
-+++ b/src/cmd/internal/obj/s390x/a.out.go
-@@ -0,0 +1,360 @@
+-In Go 1.5, as an experiment, setting the environment variable
+-GO15VENDOREXPERIMENT=1 enabled these features.
+-As of Go 1.6 they are on by default. To turn them off, set
+-GO15VENDOREXPERIMENT=0. In Go 1.7, the environment
+-variable will stop having any effect.
+-
+ See https://golang.org/s/go15vendor for details.
+ 	`,
+ }
+@@ -497,8 +491,6 @@ Special-purpose environment variables:
+ 		installed in a location other than where it is built.
+ 		File names in stack traces are rewritten from GOROOT to
+ 		GOROOT_FINAL.
+-	GO15VENDOREXPERIMENT
+-		Set to 0 to disable vendoring semantics.
+ 	GO_EXTLINK_ENABLED
+ 		Whether the linker should use external linking mode
+ 		when using -linkmode=auto with code that uses cgo.
+diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
+index 0c0cf07..6b5ead2 100644
+--- a/src/cmd/go/pkg.go
++++ b/src/cmd/go/pkg.go
+@@ -263,15 +263,6 @@ func reloadPackage(arg string, stk *importStack) *Package {
+ 	return loadPackage(arg, stk)
+ }
+ 
+-// The Go 1.5 vendoring experiment was enabled by setting GO15VENDOREXPERIMENT=1.
+-// In Go 1.6 this is on by default and is disabled by setting GO15VENDOREXPERIMENT=0.
+-// In Go 1.7 the variable will stop having any effect.
+-// The variable is obnoxiously long so that years from now when people find it in
+-// their profiles and wonder what it does, there is some chance that a web search
+-// might answer the question.
+-// There is a copy of this variable in src/go/build/build.go. Delete that one when this one goes away.
+-var go15VendorExperiment = os.Getenv("GO15VENDOREXPERIMENT") != "0"
+-
+ // dirToImportPath returns the pseudo-import path we use for a package
+ // outside the Go path.  It begins with _/ and then contains the full path
+ // to the directory.  If the package lives in c:\home\gopher\my\pkg then
+@@ -361,7 +352,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
+ 	// TODO: After Go 1, decide when to pass build.AllowBinary here.
+ 	// See issue 3268 for mistakes to avoid.
+ 	buildMode := build.ImportComment
+-	if !go15VendorExperiment || mode&useVendor == 0 || path != origPath {
++	if mode&useVendor == 0 || path != origPath {
+ 		// Not vendoring, or we already found the vendored path.
+ 		buildMode |= build.IgnoreVendor
+ 	}
+@@ -371,7 +362,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
+ 		bp.BinDir = gobin
+ 	}
+ 	if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
+-		(!go15VendorExperiment || (!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/"))) {
++		!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
+ 		err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
+ 	}
+ 	p.load(stk, bp, err)
+@@ -412,7 +403,7 @@ func isDir(path string) bool {
+ // x/vendor/path, vendor/path, or else stay path if none of those exist.
+ // vendoredImportPath returns the expanded path or, if no expansion is found, the original.
+ func vendoredImportPath(parent *Package, path string) (found string) {
+-	if parent == nil || parent.Root == "" || !go15VendorExperiment {
++	if parent == nil || parent.Root == "" {
+ 		return path
+ 	}
+ 
+@@ -580,10 +571,6 @@ func findInternal(path string) (index int, ok bool) {
+ // If the import is allowed, disallowVendor returns the original package p.
+ // If not, it returns a new package containing just an appropriate error.
+ func disallowVendor(srcDir, path string, p *Package, stk *importStack) *Package {
+-	if !go15VendorExperiment {
+-		return p
+-	}
+-
+ 	// The stack includes p.ImportPath.
+ 	// If that's the only thing on the stack, we started
+ 	// with a name given on the command line, not an
+diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
+index 342edee..797d91f 100644
+--- a/src/cmd/go/vcs.go
++++ b/src/cmd/go/vcs.go
+@@ -383,7 +383,7 @@ func (v *vcsCmd) ping(scheme, repo string) error {
+ // The parent of dir must exist; dir must not.
+ func (v *vcsCmd) create(dir, repo string) error {
+ 	for _, cmd := range v.createCmd {
+-		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
++		if strings.Contains(cmd, "submodule") {
+ 			continue
+ 		}
+ 		if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil {
+@@ -396,7 +396,7 @@ func (v *vcsCmd) create(dir, repo string) error {
+ // download downloads any new changes for the repo in dir.
+ func (v *vcsCmd) download(dir string) error {
+ 	for _, cmd := range v.downloadCmd {
+-		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
++		if strings.Contains(cmd, "submodule") {
+ 			continue
+ 		}
+ 		if err := v.run(dir, cmd); err != nil {
+@@ -445,7 +445,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
+ 
+ 	if tag == "" && v.tagSyncDefault != nil {
+ 		for _, cmd := range v.tagSyncDefault {
+-			if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
++			if strings.Contains(cmd, "submodule") {
+ 				continue
+ 			}
+ 			if err := v.run(dir, cmd); err != nil {
+@@ -456,7 +456,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
+ 	}
+ 
+ 	for _, cmd := range v.tagSyncCmd {
+-		if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
++		if strings.Contains(cmd, "submodule") {
+ 			continue
+ 		}
+ 		if err := v.run(dir, cmd, "tag", tag); err != nil {
+diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
+index 006a8c9..40fe309 100644
+--- a/src/cmd/go/vendor_test.go
++++ b/src/cmd/go/vendor_test.go
+@@ -20,7 +20,6 @@ func TestVendorImports(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("list", "-f", "{{.ImportPath}} {{.Imports}}", "vend/...")
+ 	want := `
+ 		vend [vend/vendor/p r]
+@@ -51,7 +50,6 @@ func TestVendorBuild(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("build", "vend/x")
+ }
+ 
+@@ -59,7 +57,6 @@ func TestVendorRun(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
+ 	tg.run("run", "hello.go")
+ 	tg.grepStdout("hello, world", "missing hello world output")
+@@ -74,7 +71,6 @@ func TestVendorGOPATH(t *testing.T) {
+ 	}
+ 	gopath := changeVolume(filepath.Join(tg.pwd(), "testdata"), strings.ToLower)
+ 	tg.setenv("GOPATH", gopath)
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	cd := changeVolume(filepath.Join(tg.pwd(), "testdata/src/vend/hello"), strings.ToUpper)
+ 	tg.cd(cd)
+ 	tg.run("run", "hello.go")
+@@ -85,7 +81,6 @@ func TestVendorTest(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.cd(filepath.Join(tg.pwd(), "testdata/src/vend/hello"))
+ 	tg.run("test", "-v")
+ 	tg.grepStdout("TestMsgInternal", "missing use in internal test")
+@@ -96,7 +91,6 @@ func TestVendorInvalid(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 
+ 	tg.runFail("build", "vend/x/invalid")
+ 	tg.grepStderr("must be imported as foo", "missing vendor import error")
+@@ -106,7 +100,6 @@ func TestVendorImportError(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 
+ 	tg.runFail("build", "vend/x/vendor/p/p")
+ 
+@@ -173,7 +166,6 @@ func TestVendorGet(t *testing.T) {
+ 		package p
+ 		const C = 1`)
+ 	tg.setenv("GOPATH", tg.path("."))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.cd(tg.path("src/v"))
+ 	tg.run("run", "m.go")
+ 	tg.run("test")
+@@ -192,7 +184,6 @@ func TestVendorGetUpdate(t *testing.T) {
+ 	defer tg.cleanup()
+ 	tg.makeTempdir()
+ 	tg.setenv("GOPATH", tg.path("."))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("get", "github.com/rsc/go-get-issue-11864")
+ 	tg.run("get", "-u", "github.com/rsc/go-get-issue-11864")
+ }
+@@ -204,7 +195,6 @@ func TestGetSubmodules(t *testing.T) {
+ 	defer tg.cleanup()
+ 	tg.makeTempdir()
+ 	tg.setenv("GOPATH", tg.path("."))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("get", "-d", "github.com/rsc/go-get-issue-12612")
+ 	tg.run("get", "-u", "-d", "github.com/rsc/go-get-issue-12612")
+ }
+@@ -213,7 +203,6 @@ func TestVendorCache(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.runFail("build", "p")
+ 	tg.grepStderr("must be imported as x", "did not fail to build p")
+ }
+@@ -225,7 +214,6 @@ func TestVendorTest2(t *testing.T) {
+ 	defer tg.cleanup()
+ 	tg.makeTempdir()
+ 	tg.setenv("GOPATH", tg.path("."))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("get", "github.com/rsc/go-get-issue-11864")
+ 
+ 	// build -i should work
+@@ -251,7 +239,6 @@ func TestVendorList(t *testing.T) {
+ 	defer tg.cleanup()
+ 	tg.makeTempdir()
+ 	tg.setenv("GOPATH", tg.path("."))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.run("get", "github.com/rsc/go-get-issue-11864")
+ 
+ 	tg.run("list", "-f", `{{join .TestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/t")
+@@ -272,7 +259,6 @@ func TestVendor12156(t *testing.T) {
+ 	tg := testgo(t)
+ 	defer tg.cleanup()
+ 	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor2"))
+-	tg.setenv("GO15VENDOREXPERIMENT", "1")
+ 	tg.cd(filepath.Join(tg.pwd(), "testdata/testvendor2/src/p"))
+ 	tg.runFail("build", "p.go")
+ 	tg.grepStderrNot("panic", "panicked")
+diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go
+index cfebeff..b10b804 100644
+--- a/src/cmd/gofmt/gofmt.go
++++ b/src/cmd/gofmt/gofmt.go
+@@ -143,7 +143,9 @@ func visitFile(path string, f os.FileInfo, err error) error {
+ 	if err == nil && isGoFile(f) {
+ 		err = processFile(path, nil, os.Stdout, false)
+ 	}
+-	if err != nil {
++	// Don't complain if a file was deleted in the meantime (i.e.
++	// the directory changed concurrently while running gofmt).
++	if err != nil && !os.IsNotExist(err) {
+ 		report(err)
+ 	}
+ 	return nil
+diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
+index 762a49e..465e4d0 100644
+--- a/src/cmd/internal/obj/link.go
++++ b/src/cmd/internal/obj/link.go
+@@ -521,6 +521,9 @@ const (
+ 	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the
+ 	// relocated symbol rather than the symbol's address.
+ 	R_ADDRPOWER_TOCREL_DS
++
++	// R_PCRELDBL is for S390x (z) 2-byte aligned addresses (e.g. R_390_PLT32DBL)
++	R_PCRELDBL
+ )
+ 
+ type Auto struct {
+diff --git a/src/cmd/internal/obj/obj.go b/src/cmd/internal/obj/obj.go
+index 30ab549..343c93a 100644
+--- a/src/cmd/internal/obj/obj.go
++++ b/src/cmd/internal/obj/obj.go
+@@ -281,3 +281,21 @@ func linkgetline(ctxt *Link, lineno int32, f **LSym, l *int32) {
+ func Linkprfile(ctxt *Link, line int) {
+ 	fmt.Printf("%s ", ctxt.LineHist.LineString(line))
+ }
++
++func fieldtrack(ctxt *Link, cursym *LSym) {
++	p := cursym.Text
++	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
++		return
++	}
++	ctxt.Cursym = cursym
++
++	for ; p != nil; p = p.Link {
++		if p.As == AUSEFIELD {
++			r := Addrel(ctxt.Cursym)
++			r.Off = 0
++			r.Siz = 0
++			r.Sym = p.From.Sym
++			r.Type = R_USEFIELD
++		}
++	}
++}
+diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
+index 8d4a506..bae64f4 100644
+--- a/src/cmd/internal/obj/objfile.go
++++ b/src/cmd/internal/obj/objfile.go
+@@ -298,6 +298,7 @@ func Flushplist(ctxt *Link) {
+ 		ctxt.Arch.Follow(ctxt, s)
+ 		ctxt.Arch.Preprocess(ctxt, s)
+ 		ctxt.Arch.Assemble(ctxt, s)
++		fieldtrack(ctxt, s)
+ 		linkpcln(ctxt, s)
+ 	}
+ 
+diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go
+new file mode 100644
+index 0000000..72fd427
+--- /dev/null
++++ b/src/cmd/internal/obj/s390x/a.out.go
+@@ -0,0 +1,908 @@
 +// Based on cmd/internal/obj/ppc64/a.out.go.
 +//
 +//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
@@ -13895,6 +15475,43 @@ index 0000000..a809306
 +	REG_F14
 +	REG_F15
 +
++	// V0-V15 are aliases for F0-F15
++	// We keep them in a separate space to make printing etc. easier
++	// If the code generator ever emits vector instructions it will
++	// need to take into account the aliasing.
++	REG_V0
++	REG_V1
++	REG_V2
++	REG_V3
++	REG_V4
++	REG_V5
++	REG_V6
++	REG_V7
++	REG_V8
++	REG_V9
++	REG_V10
++	REG_V11
++	REG_V12
++	REG_V13
++	REG_V14
++	REG_V15
++	REG_V16
++	REG_V17
++	REG_V18
++	REG_V19
++	REG_V20
++	REG_V21
++	REG_V22
++	REG_V23
++	REG_V24
++	REG_V25
++	REG_V26
++	REG_V27
++	REG_V28
++	REG_V29
++	REG_V30
++	REG_V31
++
 +	REG_AR0
 +	REG_AR1
 +	REG_AR2
@@ -13958,37 +15575,36 @@ index 0000000..a809306
 +)
 +
 +const ( // comments from func aclass in asmz.go
-+	C_NONE   = iota
-+	C_REG    // general-purpose register
-+	C_FREG   // floating-point register
-+	C_AREG   // access register
-+	C_ZCON   // constant == 0
-+	C_SCON   // 0 <= constant <= 0x7fff (positive int16)
-+	C_UCON   // constant & 0xffff == 0 (int32 or uint32)
-+	C_ADDCON // 0 > constant >= -0x8000 (negative int16)
-+	C_ANDCON // constant <= 0xffff
-+	C_LCON   // constant (int32 or uint32)
-+	C_DCON   // constant (int64 or uint64)
-+	C_SACON  // computed address, 16-bit displacement, possibly SP-relative
-+	C_SECON  // computed address, 16-bit displacement, possibly SB-relative, unused?
-+	C_LACON  // computed address, 32-bit displacement, possibly SP-relative
-+	C_LECON  // computed address, 32-bit displacement, possibly SB-relative, unused?
-+	C_DACON  // computed address, 64-bit displacment?
-+	C_SBRA   // short branch
-+	C_LBRA   // long branch
-+	C_SAUTO  // short auto
-+	C_LAUTO  // long auto
-+	C_ZOREG  // heap address, register-based, displacement == 0
-+	C_SOREG  // heap address, register-based, int16 displacement
-+	C_LOREG  // heap address, register-based, int32 displacement
-+	C_TLS_LE // TLS - local exec model (for executables)
-+	C_TLS_IE // TLS - initial exec model (for shared libraries loaded at program startup)
-+	C_ANY
++	C_NONE     = iota
++	C_REG      // general-purpose register (64-bit)
++	C_FREG     // floating-point register (64-bit)
++	C_VREG     // vector register (128-bit)
++	C_AREG     // access register (32-bit)
++	C_ZCON     // constant == 0
++	C_SCON     // 0 <= constant <= 0x7fff (positive int16)
++	C_UCON     // constant & 0xffff == 0 (int16 or uint16)
++	C_ADDCON   // 0 > constant >= -0x8000 (negative int16)
++	C_ANDCON   // constant <= 0xffff
++	C_LCON     // constant (int32 or uint32)
++	C_DCON     // constant (int64 or uint64)
++	C_SACON    // computed address, 16-bit displacement, possibly SP-relative
++	C_LACON    // computed address, 32-bit displacement, possibly SP-relative
++	C_DACON    // computed address, 64-bit displacment?
++	C_SBRA     // short branch
++	C_LBRA     // long branch
++	C_SAUTO    // short auto
++	C_LAUTO    // long auto
++	C_ZOREG    // heap address, register-based, displacement == 0
++	C_SOREG    // heap address, register-based, int16 displacement
++	C_LOREG    // heap address, register-based, int32 displacement
++	C_TLS_LE   // TLS - local exec model (for executables)
++	C_TLS_IE   // TLS - initial exec model (for shared libraries loaded at program startup)
 +	C_GOK      // general address
 +	C_ADDR     // relocation for extern or static symbols
 +	C_GOTADDR  // GOT slot for a symbol in -dynlink mode
 +	C_TEXTSIZE // text size
-+	C_NCLASS   // must be the last
++	C_ANY
++	C_NCLASS // must be the last
 +)
 +
 +const (
@@ -14073,7 +15689,7 @@ index 0000000..a809306
 +	AFNMADDS
 +	AFNMSUB
 +	AFNMSUBS
-+	AFRSP
++	ALEDBR
 +	ALDEBR
 +	AFSUB
 +	AFSUBS
@@ -14157,12 +15773,524 @@ index 0000000..a809306
 +	ALA
 +	ALAY
 +
++	// load/store multiple
++	ALMY
++	ALMG
++	ASTMY
++	ASTMG
++
 +	// store clock
 +	ASTCK
 +	ASTCKC
 +	ASTCKE
 +	ASTCKF
 +
++	// macros
++	ACLEAR
++
++	// vector
++	AVA
++	AVAB
++	AVAH
++	AVAF
++	AVAG
++	AVAQ
++	AVACC
++	AVACCB
++	AVACCH
++	AVACCF
++	AVACCG
++	AVACCQ
++	AVAC
++	AVACQ
++	AVACCC
++	AVACCCQ
++	AVN
++	AVNC
++	AVAVG
++	AVAVGB
++	AVAVGH
++	AVAVGF
++	AVAVGG
++	AVAVGL
++	AVAVGLB
++	AVAVGLH
++	AVAVGLF
++	AVAVGLG
++	AVCKSM
++	AVCEQ
++	AVCEQB
++	AVCEQH
++	AVCEQF
++	AVCEQG
++	AVCEQBS
++	AVCEQHS
++	AVCEQFS
++	AVCEQGS
++	AVCH
++	AVCHB
++	AVCHH
++	AVCHF
++	AVCHG
++	AVCHBS
++	AVCHHS
++	AVCHFS
++	AVCHGS
++	AVCHL
++	AVCHLB
++	AVCHLH
++	AVCHLF
++	AVCHLG
++	AVCHLBS
++	AVCHLHS
++	AVCHLFS
++	AVCHLGS
++	AVCLZ
++	AVCLZB
++	AVCLZH
++	AVCLZF
++	AVCLZG
++	AVCTZ
++	AVCTZB
++	AVCTZH
++	AVCTZF
++	AVCTZG
++	AVEC
++	AVECB
++	AVECH
++	AVECF
++	AVECG
++	AVECL
++	AVECLB
++	AVECLH
++	AVECLF
++	AVECLG
++	AVERIM
++	AVERIMB
++	AVERIMH
++	AVERIMF
++	AVERIMG
++	AVERLL
++	AVERLLB
++	AVERLLH
++	AVERLLF
++	AVERLLG
++	AVERLLV
++	AVERLLVB
++	AVERLLVH
++	AVERLLVF
++	AVERLLVG
++	AVESLV
++	AVESLVB
++	AVESLVH
++	AVESLVF
++	AVESLVG
++	AVESL
++	AVESLB
++	AVESLH
++	AVESLF
++	AVESLG
++	AVESRA
++	AVESRAB
++	AVESRAH
++	AVESRAF
++	AVESRAG
++	AVESRAV
++	AVESRAVB
++	AVESRAVH
++	AVESRAVF
++	AVESRAVG
++	AVESRL
++	AVESRLB
++	AVESRLH
++	AVESRLF
++	AVESRLG
++	AVESRLV
++	AVESRLVB
++	AVESRLVH
++	AVESRLVF
++	AVESRLVG
++	AVX
++	AVFAE
++	AVFAEB
++	AVFAEH
++	AVFAEF
++	AVFAEBS
++	AVFAEHS
++	AVFAEFS
++	AVFAEZB
++	AVFAEZH
++	AVFAEZF
++	AVFAEZBS
++	AVFAEZHS
++	AVFAEZFS
++	AVFEE
++	AVFEEB
++	AVFEEH
++	AVFEEF
++	AVFEEBS
++	AVFEEHS
++	AVFEEFS
++	AVFEEZB
++	AVFEEZH
++	AVFEEZF
++	AVFEEZBS
++	AVFEEZHS
++	AVFEEZFS
++	AVFENE
++	AVFENEB
++	AVFENEH
++	AVFENEF
++	AVFENEBS
++	AVFENEHS
++	AVFENEFS
++	AVFENEZB
++	AVFENEZH
++	AVFENEZF
++	AVFENEZBS
++	AVFENEZHS
++	AVFENEZFS
++	AVFA
++	AVFADB
++	AWFADB
++	AWFK
++	AWFKDB
++	AVFCE
++	AVFCEDB
++	AVFCEDBS
++	AWFCEDB
++	AWFCEDBS
++	AVFCH
++	AVFCHDB
++	AVFCHDBS
++	AWFCHDB
++	AWFCHDBS
++	AVFCHE
++	AVFCHEDB
++	AVFCHEDBS
++	AWFCHEDB
++	AWFCHEDBS
++	AWFC
++	AWFCDB
++	AVCDG
++	AVCDGB
++	AWCDGB
++	AVCDLG
++	AVCDLGB
++	AWCDLGB
++	AVCGD
++	AVCGDB
++	AWCGDB
++	AVCLGD
++	AVCLGDB
++	AWCLGDB
++	AVFD
++	AVFDDB
++	AWFDDB
++	AVLDE
++	AVLDEB
++	AWLDEB
++	AVLED
++	AVLEDB
++	AWLEDB
++	AVFM
++	AVFMDB
++	AWFMDB
++	AVFMA
++	AVFMADB
++	AWFMADB
++	AVFMS
++	AVFMSDB
++	AWFMSDB
++	AVFPSO
++	AVFPSODB
++	AWFPSODB
++	AVFLCDB
++	AWFLCDB
++	AVFLNDB
++	AWFLNDB
++	AVFLPDB
++	AWFLPDB
++	AVFSQ
++	AVFSQDB
++	AWFSQDB
++	AVFS
++	AVFSDB
++	AWFSDB
++	AVFTCI
++	AVFTCIDB
++	AWFTCIDB
++	AVGFM
++	AVGFMB
++	AVGFMH
++	AVGFMF
++	AVGFMG
++	AVGFMA
++	AVGFMAB
++	AVGFMAH
++	AVGFMAF
++	AVGFMAG
++	AVGEF
++	AVGEG
++	AVGBM
++	AVZERO
++	AVONE
++	AVGM
++	AVGMB
++	AVGMH
++	AVGMF
++	AVGMG
++	AVISTR
++	AVISTRB
++	AVISTRH
++	AVISTRF
++	AVISTRBS
++	AVISTRHS
++	AVISTRFS
++	AVL
++	AVLR
++	AVLREP
++	AVLREPB
++	AVLREPH
++	AVLREPF
++	AVLREPG
++	AVLC
++	AVLCB
++	AVLCH
++	AVLCF
++	AVLCG
++	AVLEH
++	AVLEF
++	AVLEG
++	AVLEB
++	AVLEIH
++	AVLEIF
++	AVLEIG
++	AVLEIB
++	AVFI
++	AVFIDB
++	AWFIDB
++	AVLGV
++	AVLGVB
++	AVLGVH
++	AVLGVF
++	AVLGVG
++	AVLLEZ
++	AVLLEZB
++	AVLLEZH
++	AVLLEZF
++	AVLLEZG
++	AVLM
++	AVLP
++	AVLPB
++	AVLPH
++	AVLPF
++	AVLPG
++	AVLBB
++	AVLVG
++	AVLVGB
++	AVLVGH
++	AVLVGF
++	AVLVGG
++	AVLVGP
++	AVLL
++	AVMX
++	AVMXB
++	AVMXH
++	AVMXF
++	AVMXG
++	AVMXL
++	AVMXLB
++	AVMXLH
++	AVMXLF
++	AVMXLG
++	AVMRH
++	AVMRHB
++	AVMRHH
++	AVMRHF
++	AVMRHG
++	AVMRL
++	AVMRLB
++	AVMRLH
++	AVMRLF
++	AVMRLG
++	AVMN
++	AVMNB
++	AVMNH
++	AVMNF
++	AVMNG
++	AVMNL
++	AVMNLB
++	AVMNLH
++	AVMNLF
++	AVMNLG
++	AVMAE
++	AVMAEB
++	AVMAEH
++	AVMAEF
++	AVMAH
++	AVMAHB
++	AVMAHH
++	AVMAHF
++	AVMALE
++	AVMALEB
++	AVMALEH
++	AVMALEF
++	AVMALH
++	AVMALHB
++	AVMALHH
++	AVMALHF
++	AVMALO
++	AVMALOB
++	AVMALOH
++	AVMALOF
++	AVMAL
++	AVMALB
++	AVMALHW
++	AVMALF
++	AVMAO
++	AVMAOB
++	AVMAOH
++	AVMAOF
++	AVME
++	AVMEB
++	AVMEH
++	AVMEF
++	AVMH
++	AVMHB
++	AVMHH
++	AVMHF
++	AVMLE
++	AVMLEB
++	AVMLEH
++	AVMLEF
++	AVMLH
++	AVMLHB
++	AVMLHH
++	AVMLHF
++	AVMLO
++	AVMLOB
++	AVMLOH
++	AVMLOF
++	AVML
++	AVMLB
++	AVMLHW
++	AVMLF
++	AVMO
++	AVMOB
++	AVMOH
++	AVMOF
++	AVNO
++	AVNOT
++	AVO
++	AVPK
++	AVPKH
++	AVPKF
++	AVPKG
++	AVPKLS
++	AVPKLSH
++	AVPKLSF
++	AVPKLSG
++	AVPKLSHS
++	AVPKLSFS
++	AVPKLSGS
++	AVPKS
++	AVPKSH
++	AVPKSF
++	AVPKSG
++	AVPKSHS
++	AVPKSFS
++	AVPKSGS
++	AVPERM
++	AVPDI
++	AVPOPCT
++	AVREP
++	AVREPB
++	AVREPH
++	AVREPF
++	AVREPG
++	AVREPI
++	AVREPIB
++	AVREPIH
++	AVREPIF
++	AVREPIG
++	AVSCEF
++	AVSCEG
++	AVSEL
++	AVSL
++	AVSLB
++	AVSLDB
++	AVSRA
++	AVSRAB
++	AVSRL
++	AVSRLB
++	AVSEG
++	AVSEGB
++	AVSEGH
++	AVSEGF
++	AVST
++	AVSTEH
++	AVSTEF
++	AVSTEG
++	AVSTEB
++	AVSTM
++	AVSTL
++	AVSTRC
++	AVSTRCB
++	AVSTRCH
++	AVSTRCF
++	AVSTRCBS
++	AVSTRCHS
++	AVSTRCFS
++	AVSTRCZB
++	AVSTRCZH
++	AVSTRCZF
++	AVSTRCZBS
++	AVSTRCZHS
++	AVSTRCZFS
++	AVS
++	AVSB
++	AVSH
++	AVSF
++	AVSG
++	AVSQ
++	AVSCBI
++	AVSCBIB
++	AVSCBIH
++	AVSCBIF
++	AVSCBIG
++	AVSCBIQ
++	AVSBCBI
++	AVSBCBIQ
++	AVSBI
++	AVSBIQ
++	AVSUMG
++	AVSUMGH
++	AVSUMGF
++	AVSUMQ
++	AVSUMQF
++	AVSUMQG
++	AVSUM
++	AVSUMB
++	AVSUMH
++	AVTM
++	AVUPH
++	AVUPHB
++	AVUPHH
++	AVUPHF
++	AVUPLH
++	AVUPLHB
++	AVUPLHH
++	AVUPLHF
++	AVUPLL
++	AVUPLLB
++	AVUPLLH
++	AVUPLLF
++	AVUPL
++	AVUPLB
++	AVUPLHW
++	AVUPLF
++
 +	// binary
 +	ABYTE
 +	AWORD
@@ -14177,10 +16305,10 @@ index 0000000..a809306
 +)
 diff --git a/src/cmd/internal/obj/s390x/anames.go b/src/cmd/internal/obj/s390x/anames.go
 new file mode 100644
-index 0000000..b34f092
+index 0000000..0cdc0e2
 --- /dev/null
 +++ b/src/cmd/internal/obj/s390x/anames.go
-@@ -0,0 +1,152 @@
+@@ -0,0 +1,658 @@
 +// Generated by stringer -i a.out.go -o anames.go -p s390x
 +// Do not edit.
 +
@@ -14263,7 +16391,7 @@ index 0000000..b34f092
 +	"FNMADDS",
 +	"FNMSUB",
 +	"FNMSUBS",
-+	"FRSP",
++	"LEDBR",
 +	"LDEBR",
 +	"FSUB",
 +	"FSUBS",
@@ -14324,10 +16452,516 @@ index 0000000..b34f092
 +	"LARL",
 +	"LA",
 +	"LAY",
++	"LMY",
++	"LMG",
++	"STMY",
++	"STMG",
 +	"STCK",
 +	"STCKC",
 +	"STCKE",
 +	"STCKF",
++	"CLEAR",
++	"VA",
++	"VAB",
++	"VAH",
++	"VAF",
++	"VAG",
++	"VAQ",
++	"VACC",
++	"VACCB",
++	"VACCH",
++	"VACCF",
++	"VACCG",
++	"VACCQ",
++	"VAC",
++	"VACQ",
++	"VACCC",
++	"VACCCQ",
++	"VN",
++	"VNC",
++	"VAVG",
++	"VAVGB",
++	"VAVGH",
++	"VAVGF",
++	"VAVGG",
++	"VAVGL",
++	"VAVGLB",
++	"VAVGLH",
++	"VAVGLF",
++	"VAVGLG",
++	"VCKSM",
++	"VCEQ",
++	"VCEQB",
++	"VCEQH",
++	"VCEQF",
++	"VCEQG",
++	"VCEQBS",
++	"VCEQHS",
++	"VCEQFS",
++	"VCEQGS",
++	"VCH",
++	"VCHB",
++	"VCHH",
++	"VCHF",
++	"VCHG",
++	"VCHBS",
++	"VCHHS",
++	"VCHFS",
++	"VCHGS",
++	"VCHL",
++	"VCHLB",
++	"VCHLH",
++	"VCHLF",
++	"VCHLG",
++	"VCHLBS",
++	"VCHLHS",
++	"VCHLFS",
++	"VCHLGS",
++	"VCLZ",
++	"VCLZB",
++	"VCLZH",
++	"VCLZF",
++	"VCLZG",
++	"VCTZ",
++	"VCTZB",
++	"VCTZH",
++	"VCTZF",
++	"VCTZG",
++	"VEC",
++	"VECB",
++	"VECH",
++	"VECF",
++	"VECG",
++	"VECL",
++	"VECLB",
++	"VECLH",
++	"VECLF",
++	"VECLG",
++	"VERIM",
++	"VERIMB",
++	"VERIMH",
++	"VERIMF",
++	"VERIMG",
++	"VERLL",
++	"VERLLB",
++	"VERLLH",
++	"VERLLF",
++	"VERLLG",
++	"VERLLV",
++	"VERLLVB",
++	"VERLLVH",
++	"VERLLVF",
++	"VERLLVG",
++	"VESLV",
++	"VESLVB",
++	"VESLVH",
++	"VESLVF",
++	"VESLVG",
++	"VESL",
++	"VESLB",
++	"VESLH",
++	"VESLF",
++	"VESLG",
++	"VESRA",
++	"VESRAB",
++	"VESRAH",
++	"VESRAF",
++	"VESRAG",
++	"VESRAV",
++	"VESRAVB",
++	"VESRAVH",
++	"VESRAVF",
++	"VESRAVG",
++	"VESRL",
++	"VESRLB",
++	"VESRLH",
++	"VESRLF",
++	"VESRLG",
++	"VESRLV",
++	"VESRLVB",
++	"VESRLVH",
++	"VESRLVF",
++	"VESRLVG",
++	"VX",
++	"VFAE",
++	"VFAEB",
++	"VFAEH",
++	"VFAEF",
++	"VFAEBS",
++	"VFAEHS",
++	"VFAEFS",
++	"VFAEZB",
++	"VFAEZH",
++	"VFAEZF",
++	"VFAEZBS",
++	"VFAEZHS",
++	"VFAEZFS",
++	"VFEE",
++	"VFEEB",
++	"VFEEH",
++	"VFEEF",
++	"VFEEBS",
++	"VFEEHS",
++	"VFEEFS",
++	"VFEEZB",
++	"VFEEZH",
++	"VFEEZF",
++	"VFEEZBS",
++	"VFEEZHS",
++	"VFEEZFS",
++	"VFENE",
++	"VFENEB",
++	"VFENEH",
++	"VFENEF",
++	"VFENEBS",
++	"VFENEHS",
++	"VFENEFS",
++	"VFENEZB",
++	"VFENEZH",
++	"VFENEZF",
++	"VFENEZBS",
++	"VFENEZHS",
++	"VFENEZFS",
++	"VFA",
++	"VFADB",
++	"WFADB",
++	"WFK",
++	"WFKDB",
++	"VFCE",
++	"VFCEDB",
++	"VFCEDBS",
++	"WFCEDB",
++	"WFCEDBS",
++	"VFCH",
++	"VFCHDB",
++	"VFCHDBS",
++	"WFCHDB",
++	"WFCHDBS",
++	"VFCHE",
++	"VFCHEDB",
++	"VFCHEDBS",
++	"WFCHEDB",
++	"WFCHEDBS",
++	"WFC",
++	"WFCDB",
++	"VCDG",
++	"VCDGB",
++	"WCDGB",
++	"VCDLG",
++	"VCDLGB",
++	"WCDLGB",
++	"VCGD",
++	"VCGDB",
++	"WCGDB",
++	"VCLGD",
++	"VCLGDB",
++	"WCLGDB",
++	"VFD",
++	"VFDDB",
++	"WFDDB",
++	"VLDE",
++	"VLDEB",
++	"WLDEB",
++	"VLED",
++	"VLEDB",
++	"WLEDB",
++	"VFM",
++	"VFMDB",
++	"WFMDB",
++	"VFMA",
++	"VFMADB",
++	"WFMADB",
++	"VFMS",
++	"VFMSDB",
++	"WFMSDB",
++	"VFPSO",
++	"VFPSODB",
++	"WFPSODB",
++	"VFLCDB",
++	"WFLCDB",
++	"VFLNDB",
++	"WFLNDB",
++	"VFLPDB",
++	"WFLPDB",
++	"VFSQ",
++	"VFSQDB",
++	"WFSQDB",
++	"VFS",
++	"VFSDB",
++	"WFSDB",
++	"VFTCI",
++	"VFTCIDB",
++	"WFTCIDB",
++	"VGFM",
++	"VGFMB",
++	"VGFMH",
++	"VGFMF",
++	"VGFMG",
++	"VGFMA",
++	"VGFMAB",
++	"VGFMAH",
++	"VGFMAF",
++	"VGFMAG",
++	"VGEF",
++	"VGEG",
++	"VGBM",
++	"VZERO",
++	"VONE",
++	"VGM",
++	"VGMB",
++	"VGMH",
++	"VGMF",
++	"VGMG",
++	"VISTR",
++	"VISTRB",
++	"VISTRH",
++	"VISTRF",
++	"VISTRBS",
++	"VISTRHS",
++	"VISTRFS",
++	"VL",
++	"VLR",
++	"VLREP",
++	"VLREPB",
++	"VLREPH",
++	"VLREPF",
++	"VLREPG",
++	"VLC",
++	"VLCB",
++	"VLCH",
++	"VLCF",
++	"VLCG",
++	"VLEH",
++	"VLEF",
++	"VLEG",
++	"VLEB",
++	"VLEIH",
++	"VLEIF",
++	"VLEIG",
++	"VLEIB",
++	"VFI",
++	"VFIDB",
++	"WFIDB",
++	"VLGV",
++	"VLGVB",
++	"VLGVH",
++	"VLGVF",
++	"VLGVG",
++	"VLLEZ",
++	"VLLEZB",
++	"VLLEZH",
++	"VLLEZF",
++	"VLLEZG",
++	"VLM",
++	"VLP",
++	"VLPB",
++	"VLPH",
++	"VLPF",
++	"VLPG",
++	"VLBB",
++	"VLVG",
++	"VLVGB",
++	"VLVGH",
++	"VLVGF",
++	"VLVGG",
++	"VLVGP",
++	"VLL",
++	"VMX",
++	"VMXB",
++	"VMXH",
++	"VMXF",
++	"VMXG",
++	"VMXL",
++	"VMXLB",
++	"VMXLH",
++	"VMXLF",
++	"VMXLG",
++	"VMRH",
++	"VMRHB",
++	"VMRHH",
++	"VMRHF",
++	"VMRHG",
++	"VMRL",
++	"VMRLB",
++	"VMRLH",
++	"VMRLF",
++	"VMRLG",
++	"VMN",
++	"VMNB",
++	"VMNH",
++	"VMNF",
++	"VMNG",
++	"VMNL",
++	"VMNLB",
++	"VMNLH",
++	"VMNLF",
++	"VMNLG",
++	"VMAE",
++	"VMAEB",
++	"VMAEH",
++	"VMAEF",
++	"VMAH",
++	"VMAHB",
++	"VMAHH",
++	"VMAHF",
++	"VMALE",
++	"VMALEB",
++	"VMALEH",
++	"VMALEF",
++	"VMALH",
++	"VMALHB",
++	"VMALHH",
++	"VMALHF",
++	"VMALO",
++	"VMALOB",
++	"VMALOH",
++	"VMALOF",
++	"VMAL",
++	"VMALB",
++	"VMALHW",
++	"VMALF",
++	"VMAO",
++	"VMAOB",
++	"VMAOH",
++	"VMAOF",
++	"VME",
++	"VMEB",
++	"VMEH",
++	"VMEF",
++	"VMH",
++	"VMHB",
++	"VMHH",
++	"VMHF",
++	"VMLE",
++	"VMLEB",
++	"VMLEH",
++	"VMLEF",
++	"VMLH",
++	"VMLHB",
++	"VMLHH",
++	"VMLHF",
++	"VMLO",
++	"VMLOB",
++	"VMLOH",
++	"VMLOF",
++	"VML",
++	"VMLB",
++	"VMLHW",
++	"VMLF",
++	"VMO",
++	"VMOB",
++	"VMOH",
++	"VMOF",
++	"VNO",
++	"VNOT",
++	"VO",
++	"VPK",
++	"VPKH",
++	"VPKF",
++	"VPKG",
++	"VPKLS",
++	"VPKLSH",
++	"VPKLSF",
++	"VPKLSG",
++	"VPKLSHS",
++	"VPKLSFS",
++	"VPKLSGS",
++	"VPKS",
++	"VPKSH",
++	"VPKSF",
++	"VPKSG",
++	"VPKSHS",
++	"VPKSFS",
++	"VPKSGS",
++	"VPERM",
++	"VPDI",
++	"VPOPCT",
++	"VREP",
++	"VREPB",
++	"VREPH",
++	"VREPF",
++	"VREPG",
++	"VREPI",
++	"VREPIB",
++	"VREPIH",
++	"VREPIF",
++	"VREPIG",
++	"VSCEF",
++	"VSCEG",
++	"VSEL",
++	"VSL",
++	"VSLB",
++	"VSLDB",
++	"VSRA",
++	"VSRAB",
++	"VSRL",
++	"VSRLB",
++	"VSEG",
++	"VSEGB",
++	"VSEGH",
++	"VSEGF",
++	"VST",
++	"VSTEH",
++	"VSTEF",
++	"VSTEG",
++	"VSTEB",
++	"VSTM",
++	"VSTL",
++	"VSTRC",
++	"VSTRCB",
++	"VSTRCH",
++	"VSTRCF",
++	"VSTRCBS",
++	"VSTRCHS",
++	"VSTRCFS",
++	"VSTRCZB",
++	"VSTRCZH",
++	"VSTRCZF",
++	"VSTRCZBS",
++	"VSTRCZHS",
++	"VSTRCZFS",
++	"VS",
++	"VSB",
++	"VSH",
++	"VSF",
++	"VSG",
++	"VSQ",
++	"VSCBI",
++	"VSCBIB",
++	"VSCBIH",
++	"VSCBIF",
++	"VSCBIG",
++	"VSCBIQ",
++	"VSBCBI",
++	"VSBCBIQ",
++	"VSBI",
++	"VSBIQ",
++	"VSUMG",
++	"VSUMGH",
++	"VSUMGF",
++	"VSUMQ",
++	"VSUMQF",
++	"VSUMQG",
++	"VSUM",
++	"VSUMB",
++	"VSUMH",
++	"VTM",
++	"VUPH",
++	"VUPHB",
++	"VUPHH",
++	"VUPHF",
++	"VUPLH",
++	"VUPLHB",
++	"VUPLHH",
++	"VUPLHF",
++	"VUPLL",
++	"VUPLLB",
++	"VUPLLH",
++	"VUPLLF",
++	"VUPL",
++	"VUPLB",
++	"VUPLHW",
++	"VUPLF",
 +	"BYTE",
 +	"WORD",
 +	"DWORD",
@@ -14335,16 +16969,17 @@ index 0000000..b34f092
 +}
 diff --git a/src/cmd/internal/obj/s390x/anamesz.go b/src/cmd/internal/obj/s390x/anamesz.go
 new file mode 100644
-index 0000000..75823c2
+index 0000000..bc5f969
 --- /dev/null
 +++ b/src/cmd/internal/obj/s390x/anamesz.go
-@@ -0,0 +1,35 @@
+@@ -0,0 +1,34 @@
 +package s390x
 +
 +var cnamesz = []string{
 +	"NONE",
 +	"REG",
 +	"FREG",
++	"VREG",
 +	"AREG",
 +	"ZCON",
 +	"SCON",
@@ -14354,9 +16989,7 @@ index 0000000..75823c2
 +	"LCON",
 +	"DCON",
 +	"SACON",
-+	"SECON",
 +	"LACON",
-+	"LECON",
 +	"DACON",
 +	"SBRA",
 +	"LBRA",
@@ -14367,19 +17000,19 @@ index 0000000..75823c2
 +	"LOREG",
 +	"TLS_LE",
 +	"TLS_IE",
-+	"ANY",
 +	"GOK",
 +	"ADDR",
 +	"GOTADDR",
 +	"TEXTSIZE",
++	"ANY",
 +	"NCLASS",
 +}
 diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
 new file mode 100644
-index 0000000..7956f22
+index 0000000..82b07bb
 --- /dev/null
 +++ b/src/cmd/internal/obj/s390x/asmz.go
-@@ -0,0 +1,4017 @@
+@@ -0,0 +1,5177 @@
 +// Based on cmd/internal/obj/ppc64/asm9.go.
 +//
 +//    Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
@@ -14448,32 +17081,18 @@ index 0000000..7956f22
 +	Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 0},
 +	Optab{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 0},
 +	Optab{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
-+	Optab{AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 0},
-+	Optab{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 0},
-+	Optab{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 0},
-+	Optab{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 0},
 +	Optab{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
 +	Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
 +	Optab{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 0},
 +	Optab{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
-+	Optab{AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 0},
-+	Optab{AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 0},
 +	Optab{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
 +	Optab{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
 +	Optab{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 0}, /* logical, no literal */
 +	Optab{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
-+	Optab{AAND, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 0},
-+	Optab{AAND, C_ANDCON, C_REG, C_NONE, C_REG, 58, 0},
-+	Optab{AAND, C_UCON, C_NONE, C_NONE, C_REG, 59, 0},
-+	Optab{AAND, C_UCON, C_REG, C_NONE, C_REG, 59, 0},
 +	Optab{AAND, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
 +	Optab{AAND, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
 +	Optab{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 0},
 +	Optab{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 0},
-+	Optab{AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 0},
-+	Optab{AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 0},
-+	Optab{AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 0},
-+	Optab{AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 0},
 +	Optab{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 0},
 +	Optab{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 0},
 +	Optab{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 0},
@@ -14482,10 +17101,6 @@ index 0000000..7956f22
 +	Optab{ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 0},
 +	Optab{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 0}, /* logical, literal not cc (or/xor) */
 +	Optab{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
-+	Optab{AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 0},
-+	Optab{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 0},
-+	Optab{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 0},
-+	Optab{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 0},
 +	Optab{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
 +	Optab{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
 +	Optab{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 0}, /* op r1[,r2],r3 */
@@ -14516,13 +17131,13 @@ index 0000000..7956f22
 +	Optab{ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 0},
 +	Optab{ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 0},
 +	Optab{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 0},
-+	Optab{AFADD, C_FREG, C_REG, C_NONE, C_FREG, 2, 0},
++	Optab{AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 0},
 +	Optab{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 0},
 +	Optab{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 0},
 +	Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 0},
-+	Optab{AFMADD, C_FREG, C_REG, C_FREG, C_FREG, 34, 0},
++	Optab{AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 0},
 +	Optab{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 0},
-+	Optab{AFMUL, C_FREG, C_REG, C_NONE, C_FREG, 32, 0},
++	Optab{AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 0},
 +	Optab{ACS, C_REG, C_REG, C_NONE, C_SOREG, 79, 0},
 +	Optab{ACSG, C_REG, C_REG, C_NONE, C_SOREG, 79, 0},
 +	Optab{ACEFBRA, C_REG, C_NONE, C_NONE, C_FREG, 82, 0},
@@ -14530,6 +17145,7 @@ index 0000000..7956f22
 +	Optab{AMVC, C_SOREG, C_NONE, C_SCON, C_SOREG, 84, 0},
 +	Optab{ALARL, C_LCON, C_NONE, C_NONE, C_REG, 85, 0},
 +	Optab{ALA, C_SOREG, C_NONE, C_NONE, C_REG, 86, 0},
++	Optab{ALA, C_SAUTO, C_NONE, C_NONE, C_REG, 86, REGSP},
 +	Optab{AEXRL, C_LCON, C_NONE, C_NONE, C_REG, 87, 0},
 +	Optab{ASTCK, C_NONE, C_NONE, C_NONE, C_SAUTO, 88, REGSP},
 +	Optab{ASTCK, C_NONE, C_NONE, C_NONE, C_SOREG, 88, 0},
@@ -14603,16 +17219,21 @@ index 0000000..7956f22
 +	Optab{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 0},
 +
 +	/* store constant */
-+	Optab{AMOVD, C_SCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVW, C_SCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVWZ, C_SCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVB, C_SCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVBZ, C_SCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVD, C_ADDCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVW, C_ADDCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVB, C_ADDCON, C_NONE, C_NONE, C_SOREG, 92, 0},
-+	Optab{AMOVBZ, C_ADDCON, C_NONE, C_NONE, C_SOREG, 92, 0},
++	Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0},
++	Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0},
++	Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0},
++	Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0},
++	Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_ADDR, 73, 0},
++	Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_SAUTO, 72, REGSP},
++	Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_SAUTO, 72, REGSP},
++	Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_SAUTO, 72, REGSP},
++	Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_SAUTO, 72, REGSP},
++	Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_SAUTO, 72, REGSP},
++	Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_SOREG, 72, 0},
++	Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_SOREG, 72, 0},
++	Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_SOREG, 72, 0},
++	Optab{AMOVB, C_LCON, C_NONE, C_NONE, C_SOREG, 72, 0},
++	Optab{AMOVBZ, C_LCON, C_NONE, C_NONE, C_SOREG, 72, 0},
 +
 +	/* load constant */
 +	Optab{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, REGSP},
@@ -14627,7 +17248,8 @@ index 0000000..7956f22
 +	Optab{AMOVB, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 0},
 +	Optab{AMOVBZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 0},
 +	Optab{AMOVB, C_SCON, C_NONE, C_NONE, C_REG, 3, 0},
-+	Optab{AMOVBZ, C_SCON, C_NONE, C_NONE, C_REG, 3, 0},
++	Optab{AMOVBZ, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 0},
++	Optab{AMOVBZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 0},
 +
 +	/* load unsigned/long constants (TODO: check) */
 +	Optab{AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 0},
@@ -14705,6 +17327,118 @@ index 0000000..7956f22
 +	Optab{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 0},
 +	Optab{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 0},
 +
++	// macros
++	Optab{ACLEAR, C_LCON, C_NONE, C_NONE, C_LOREG, 96, 0},
++	Optab{ACLEAR, C_LCON, C_NONE, C_NONE, C_LAUTO, 96, REGSP},
++
++	///////////////////////////////////////////////////////////////////////
++	// vector instructions
++	///////////////////////////////////////////////////////////////////////
++
++	// VRX store
++	Optab{AVST, C_VREG, C_NONE, C_NONE, C_SOREG, 100, 0},
++	Optab{AVST, C_VREG, C_NONE, C_NONE, C_SAUTO, 100, REGSP},
++	Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SOREG, 100, 0},
++	Optab{AVSTEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 100, REGSP},
++
++	// VRX load
++	Optab{AVL, C_SOREG, C_NONE, C_NONE, C_VREG, 101, 0},
++	Optab{AVL, C_SAUTO, C_NONE, C_NONE, C_VREG, 101, REGSP},
++	Optab{AVLEG, C_SOREG, C_NONE, C_SCON, C_VREG, 101, 0},
++	Optab{AVLEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 101, REGSP},
++
++	// VRV scatter
++	Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SOREG, 102, 0},
++	Optab{AVSCEG, C_VREG, C_NONE, C_SCON, C_SAUTO, 102, REGSP},
++
++	// VRV gather
++	Optab{AVGEG, C_SOREG, C_NONE, C_SCON, C_VREG, 103, 0},
++	Optab{AVGEG, C_SAUTO, C_NONE, C_SCON, C_VREG, 103, REGSP},
++
++	// VRS element shift/rotate and load gr to/from vr element
++	Optab{AVESLG, C_SCON, C_VREG, C_NONE, C_VREG, 104, 0},
++	Optab{AVESLG, C_REG, C_VREG, C_NONE, C_VREG, 104, 0},
++	Optab{AVESLG, C_SCON, C_NONE, C_NONE, C_VREG, 104, 0},
++	Optab{AVESLG, C_REG, C_NONE, C_NONE, C_VREG, 104, 0},
++	Optab{AVLGVG, C_SCON, C_VREG, C_NONE, C_REG, 104, 0},
++	Optab{AVLGVG, C_REG, C_VREG, C_NONE, C_REG, 104, 0},
++	Optab{AVLVGG, C_SCON, C_REG, C_NONE, C_VREG, 104, 0},
++	Optab{AVLVGG, C_REG, C_REG, C_NONE, C_VREG, 104, 0},
++
++	// VRS store multiple
++	Optab{AVSTM, C_VREG, C_VREG, C_NONE, C_SOREG, 105, 0},
++	Optab{AVSTM, C_VREG, C_VREG, C_NONE, C_SAUTO, 105, REGSP},
++
++	// VRS load multiple
++	Optab{AVLM, C_SOREG, C_VREG, C_NONE, C_VREG, 106, 0},
++	Optab{AVLM, C_SAUTO, C_VREG, C_NONE, C_VREG, 106, REGSP},
++
++	// VRS store with length
++	Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SOREG, 107, 0},
++	Optab{AVSTL, C_VREG, C_NONE, C_REG, C_SAUTO, 107, REGSP},
++
++	// VRS load with length
++	Optab{AVLL, C_SOREG, C_NONE, C_REG, C_VREG, 108, 0},
++	Optab{AVLL, C_SAUTO, C_NONE, C_REG, C_VREG, 108, REGSP},
++
++	// VRI-a
++	Optab{AVGBM, C_ANDCON, C_NONE, C_NONE, C_VREG, 109, 0},
++	Optab{AVZERO, C_NONE, C_NONE, C_NONE, C_VREG, 109, 0},
++	Optab{AVREPIG, C_ADDCON, C_NONE, C_NONE, C_VREG, 109, 0},
++	Optab{AVREPIG, C_SCON, C_NONE, C_NONE, C_VREG, 109, 0},
++	Optab{AVLEIG, C_ADDCON, C_NONE, C_SCON, C_VREG, 109, 0},
++	Optab{AVLEIG, C_SCON, C_NONE, C_SCON, C_VREG, 109, 0},
++
++	// VRI-b generate mask
++	Optab{AVGMG, C_SCON, C_NONE, C_SCON, C_VREG, 110, 0},
++
++	// VRI-c replicate
++	Optab{AVREPG, C_UCON, C_VREG, C_NONE, C_VREG, 111, 0},
++
++	// VRI-d element rotate and insert under mask and
++	// shift left double by byte
++	Optab{AVERIMG, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0},
++	Optab{AVSLDB, C_VREG, C_VREG, C_SCON, C_VREG, 112, 0},
++
++	// VRI-d fp test data class immediate
++	Optab{AVFTCIDB, C_SCON, C_VREG, C_NONE, C_VREG, 113, 0},
++
++	// VRR-a load reg
++	Optab{AVLR, C_VREG, C_NONE, C_NONE, C_VREG, 114, 0},
++
++	// VRR-a compare
++	Optab{AVECG, C_VREG, C_NONE, C_NONE, C_VREG, 115, 0},
++
++	// VRR-b
++	Optab{AVCEQG, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0},
++	Optab{AVFAEF, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0},
++	Optab{AVPKSG, C_VREG, C_VREG, C_NONE, C_VREG, 117, 0},
++
++	// VRR-c
++	Optab{AVAQ, C_VREG, C_VREG, C_NONE, C_VREG, 118, 0},
++	Optab{AVAQ, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0},
++	Optab{AVNOT, C_VREG, C_NONE, C_NONE, C_VREG, 118, 0},
++
++	// VRR-c shifts
++	Optab{AVERLLVG, C_VREG, C_VREG, C_NONE, C_VREG, 119, 0},
++	Optab{AVERLLVG, C_VREG, C_NONE, C_NONE, C_VREG, 119, 0},
++
++	// VRR-d
++	//             2       3       1       4
++	Optab{AVACQ, C_VREG, C_VREG, C_VREG, C_VREG, 120, 0},
++
++	// VRR-e
++	Optab{AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 121, 0},
++
++	// VRR-f
++	Optab{AVLVGP, C_REG, C_REG, C_NONE, C_VREG, 122, 0},
++
++	// load/store multiple
++	Optab{ASTMG, C_REG, C_REG, C_NONE, C_LOREG, 97, 0},
++	Optab{ASTMG, C_REG, C_REG, C_NONE, C_LAUTO, 97, REGSP},
++	Optab{ALMG, C_LOREG, C_REG, C_NONE, C_REG, 98, 0},
++	Optab{ALMG, C_LAUTO, C_REG, C_NONE, C_REG, 98, REGSP},
++
 +	Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 0},
 +	Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0},
 +	Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0},
@@ -14792,6 +17526,9 @@ index 0000000..7956f22
 +		if REG_AR0 <= a.Reg && a.Reg <= REG_AR15 {
 +			return C_AREG
 +		}
++		if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
++			return C_VREG
++		}
 +		return C_GOK
 +
 +	case obj.TYPE_MEM:
@@ -14866,14 +17603,11 @@ index 0000000..7956f22
 +			if s == nil {
 +				break
 +			}
++			ctxt.Instoffset = s.Value + a.Offset
 +			if s.Type == obj.SCONST {
-+				ctxt.Instoffset = s.Value + a.Offset
 +				goto consize
 +			}
 +
-+			ctxt.Instoffset = s.Value + a.Offset
-+
-+			/* not sure why this barfs */
 +			return C_LCON
 +
 +		case obj.NAME_AUTO:
@@ -14959,7 +17693,15 @@ index 0000000..7956f22
 +	a4--
 +	a2 := C_NONE
 +	if p.Reg != 0 {
-+		a2 = C_REG
++		if REG_R0 <= p.Reg && p.Reg <= REG_R15 {
++			a2 = C_REG
++		} else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
++			a2 = C_VREG
++		} else if REG_F0 <= p.Reg && p.Reg <= REG_F15 {
++			a2 = C_FREG
++		} else if REG_AR0 <= p.Reg && p.Reg <= REG_AR15 {
++			a2 = C_AREG
++		}
 +	}
 +
 +	r0 := p.As & obj.AMask
@@ -15013,7 +17755,7 @@ index 0000000..7956f22
 +		}
 +
 +	case C_UCON:
-+		if b == C_ZCON {
++		if b == C_ZCON || b == C_SCON {
 +			return true
 +		}
 +
@@ -15166,6 +17908,14 @@ index 0000000..7956f22
 +			opset(ASTCKE, r0)
 +			opset(ASTCKF, r0)
 +
++		case ACLEAR:
++
++		case ASTMG:
++			opset(ASTMY, r0)
++
++		case ALMG:
++			opset(ALMY, r0)
++
 +		case AAND: /* logical op Rb,Rs,Ra; no literal */
 +			opset(AANDN, r0)
 +			opset(ANAND, r0)
@@ -15197,7 +17947,7 @@ index 0000000..7956f22
 +		case AFABS: /* fop [s,]d */
 +			opset(AFNABS, r0)
 +			opset(AFNEG, r0)
-+			opset(AFRSP, r0)
++			opset(ALEDBR, r0)
 +			opset(ALDEBR, r0)
 +			opset(AFSQRT, r0)
 +			opset(AFSQRTS, r0)
@@ -15304,6 +18054,430 @@ index 0000000..7956f22
 +			opset(ACMPUBLT, r0)
 +			opset(ACMPUBNE, r0)
 +
++		case AVL:
++			opset(AVLLEZB, r0)
++			opset(AVLLEZH, r0)
++			opset(AVLLEZF, r0)
++			opset(AVLLEZG, r0)
++			opset(AVLREPB, r0)
++			opset(AVLREPH, r0)
++			opset(AVLREPF, r0)
++			opset(AVLREPG, r0)
++
++		case AVST:
++
++		case AVLEG:
++			opset(AVLBB, r0)
++			opset(AVLEB, r0)
++			opset(AVLEH, r0)
++			opset(AVLEF, r0)
++			opset(AVLEG, r0)
++			opset(AVLREP, r0)
++
++		case AVSTEG:
++			opset(AVSTEB, r0)
++			opset(AVSTEH, r0)
++			opset(AVSTEF, r0)
++
++		case AVSCEG:
++			opset(AVSCEF, r0)
++
++		case AVGEG:
++			opset(AVGEF, r0)
++
++		case AVESLG:
++			opset(AVESLB, r0)
++			opset(AVESLH, r0)
++			opset(AVESLF, r0)
++			opset(AVERLLB, r0)
++			opset(AVERLLH, r0)
++			opset(AVERLLF, r0)
++			opset(AVERLLG, r0)
++			opset(AVESRAB, r0)
++			opset(AVESRAH, r0)
++			opset(AVESRAF, r0)
++			opset(AVESRAG, r0)
++			opset(AVESRLB, r0)
++			opset(AVESRLH, r0)
++			opset(AVESRLF, r0)
++			opset(AVESRLG, r0)
++
++		case AVLGVG:
++			opset(AVLGVB, r0)
++			opset(AVLGVH, r0)
++			opset(AVLGVF, r0)
++
++		case AVLVGG:
++			opset(AVLVGB, r0)
++			opset(AVLVGH, r0)
++			opset(AVLVGF, r0)
++
++		case AVLL:
++
++		case AVSTL:
++
++		case AVLM:
++
++		case AVSTM:
++
++		case AVGBM:
++
++		case AVZERO:
++			opset(AVONE, r0)
++
++		case AVREPIG:
++			opset(AVREPIB, r0)
++			opset(AVREPIH, r0)
++			opset(AVREPIF, r0)
++
++		case AVLEIG:
++			opset(AVLEIB, r0)
++			opset(AVLEIH, r0)
++			opset(AVLEIF, r0)
++
++		case AVGMG:
++			opset(AVGMB, r0)
++			opset(AVGMH, r0)
++			opset(AVGMF, r0)
++
++		case AVREPG:
++			opset(AVREPB, r0)
++			opset(AVREPH, r0)
++			opset(AVREPF, r0)
++
++		case AVERIMG:
++			opset(AVERIMB, r0)
++			opset(AVERIMH, r0)
++			opset(AVERIMF, r0)
++
++		case AVSLDB:
++
++		case AVFTCIDB:
++			opset(AWFTCIDB, r0)
++
++		case AVLR:
++			opset(AVUPHB, r0)
++			opset(AVUPHH, r0)
++			opset(AVUPHF, r0)
++			opset(AVUPLHB, r0)
++			opset(AVUPLHH, r0)
++			opset(AVUPLHF, r0)
++			opset(AVUPLB, r0)
++			opset(AVUPLHW, r0)
++			opset(AVUPLF, r0)
++			opset(AVUPLLB, r0)
++			opset(AVUPLLH, r0)
++			opset(AVUPLLF, r0)
++			opset(AVCLZB, r0)
++			opset(AVCLZH, r0)
++			opset(AVCLZF, r0)
++			opset(AVCLZG, r0)
++			opset(AVCTZB, r0)
++			opset(AVCTZH, r0)
++			opset(AVCTZF, r0)
++			opset(AVCTZG, r0)
++			opset(AVLDEB, r0)
++			opset(AWLDEB, r0)
++			opset(AVFLCDB, r0)
++			opset(AWFLCDB, r0)
++			opset(AVFLNDB, r0)
++			opset(AWFLNDB, r0)
++			opset(AVFLPDB, r0)
++			opset(AWFLPDB, r0)
++			opset(AVFSQDB, r0)
++			opset(AWFSQDB, r0)
++			opset(AVISTRB, r0)
++			opset(AVISTRH, r0)
++			opset(AVISTRF, r0)
++			opset(AVISTRBS, r0)
++			opset(AVISTRHS, r0)
++			opset(AVISTRFS, r0)
++			opset(AVLCB, r0)
++			opset(AVLCH, r0)
++			opset(AVLCF, r0)
++			opset(AVLCG, r0)
++			opset(AVLPB, r0)
++			opset(AVLPH, r0)
++			opset(AVLPF, r0)
++			opset(AVLPG, r0)
++			opset(AVPOPCT, r0)
++			opset(AVSEGB, r0)
++			opset(AVSEGH, r0)
++			opset(AVSEGF, r0)
++
++		case AVECG:
++			opset(AVECB, r0)
++			opset(AVECH, r0)
++			opset(AVECF, r0)
++			opset(AVECLB, r0)
++			opset(AVECLH, r0)
++			opset(AVECLF, r0)
++			opset(AVECLG, r0)
++			opset(AWFCDB, r0)
++			opset(AWFKDB, r0)
++
++		case AVCEQG:
++			opset(AVCEQB, r0)
++			opset(AVCEQH, r0)
++			opset(AVCEQF, r0)
++			opset(AVCEQBS, r0)
++			opset(AVCEQHS, r0)
++			opset(AVCEQFS, r0)
++			opset(AVCEQGS, r0)
++			opset(AVCHB, r0)
++			opset(AVCHH, r0)
++			opset(AVCHF, r0)
++			opset(AVCHG, r0)
++			opset(AVCHBS, r0)
++			opset(AVCHHS, r0)
++			opset(AVCHFS, r0)
++			opset(AVCHGS, r0)
++			opset(AVCHLB, r0)
++			opset(AVCHLH, r0)
++			opset(AVCHLF, r0)
++			opset(AVCHLG, r0)
++			opset(AVCHLBS, r0)
++			opset(AVCHLHS, r0)
++			opset(AVCHLFS, r0)
++			opset(AVCHLGS, r0)
++
++		case AVFAEF:
++			opset(AVFAEB, r0)
++			opset(AVFAEH, r0)
++			opset(AVFAEBS, r0)
++			opset(AVFAEHS, r0)
++			opset(AVFAEFS, r0)
++			opset(AVFAEZB, r0)
++			opset(AVFAEZH, r0)
++			opset(AVFAEZF, r0)
++			opset(AVFAEZBS, r0)
++			opset(AVFAEZHS, r0)
++			opset(AVFAEZFS, r0)
++			opset(AVFEEB, r0)
++			opset(AVFEEH, r0)
++			opset(AVFEEF, r0)
++			opset(AVFEEBS, r0)
++			opset(AVFEEHS, r0)
++			opset(AVFEEFS, r0)
++			opset(AVFEEZB, r0)
++			opset(AVFEEZH, r0)
++			opset(AVFEEZF, r0)
++			opset(AVFEEZBS, r0)
++			opset(AVFEEZHS, r0)
++			opset(AVFEEZFS, r0)
++			opset(AVFENEB, r0)
++			opset(AVFENEH, r0)
++			opset(AVFENEF, r0)
++			opset(AVFENEBS, r0)
++			opset(AVFENEHS, r0)
++			opset(AVFENEFS, r0)
++			opset(AVFENEZB, r0)
++			opset(AVFENEZH, r0)
++			opset(AVFENEZF, r0)
++			opset(AVFENEZBS, r0)
++			opset(AVFENEZHS, r0)
++			opset(AVFENEZFS, r0)
++
++		case AVPKSG:
++			opset(AVPKSH, r0)
++			opset(AVPKSF, r0)
++			opset(AVPKSHS, r0)
++			opset(AVPKSFS, r0)
++			opset(AVPKSGS, r0)
++			opset(AVPKLSH, r0)
++			opset(AVPKLSF, r0)
++			opset(AVPKLSG, r0)
++			opset(AVPKLSHS, r0)
++			opset(AVPKLSFS, r0)
++			opset(AVPKLSGS, r0)
++
++		case AVAQ:
++			opset(AVAB, r0)
++			opset(AVAH, r0)
++			opset(AVAF, r0)
++			opset(AVAG, r0)
++			opset(AVACCB, r0)
++			opset(AVACCH, r0)
++			opset(AVACCF, r0)
++			opset(AVACCG, r0)
++			opset(AVACCQ, r0)
++			opset(AVN, r0)
++			opset(AVNC, r0)
++			opset(AVAVGB, r0)
++			opset(AVAVGH, r0)
++			opset(AVAVGF, r0)
++			opset(AVAVGG, r0)
++			opset(AVAVGLB, r0)
++			opset(AVAVGLH, r0)
++			opset(AVAVGLF, r0)
++			opset(AVAVGLG, r0)
++			opset(AVCKSM, r0)
++			opset(AVX, r0)
++			opset(AVFADB, r0)
++			opset(AWFADB, r0)
++			opset(AVFCEDB, r0)
++			opset(AVFCEDBS, r0)
++			opset(AWFCEDB, r0)
++			opset(AWFCEDBS, r0)
++			opset(AVFCHDB, r0)
++			opset(AVFCHDBS, r0)
++			opset(AWFCHDB, r0)
++			opset(AWFCHDBS, r0)
++			opset(AVFCHEDB, r0)
++			opset(AVFCHEDBS, r0)
++			opset(AWFCHEDB, r0)
++			opset(AWFCHEDBS, r0)
++			opset(AVFMDB, r0)
++			opset(AWFMDB, r0)
++			opset(AVGFMB, r0)
++			opset(AVGFMH, r0)
++			opset(AVGFMF, r0)
++			opset(AVGFMG, r0)
++			opset(AVMXB, r0)
++			opset(AVMXH, r0)
++			opset(AVMXF, r0)
++			opset(AVMXG, r0)
++			opset(AVMXLB, r0)
++			opset(AVMXLH, r0)
++			opset(AVMXLF, r0)
++			opset(AVMXLG, r0)
++			opset(AVMNB, r0)
++			opset(AVMNH, r0)
++			opset(AVMNF, r0)
++			opset(AVMNG, r0)
++			opset(AVMNLB, r0)
++			opset(AVMNLH, r0)
++			opset(AVMNLF, r0)
++			opset(AVMNLG, r0)
++			opset(AVMRHB, r0)
++			opset(AVMRHH, r0)
++			opset(AVMRHF, r0)
++			opset(AVMRHG, r0)
++			opset(AVMRLB, r0)
++			opset(AVMRLH, r0)
++			opset(AVMRLF, r0)
++			opset(AVMRLG, r0)
++			opset(AVMEB, r0)
++			opset(AVMEH, r0)
++			opset(AVMEF, r0)
++			opset(AVMLEB, r0)
++			opset(AVMLEH, r0)
++			opset(AVMLEF, r0)
++			opset(AVMOB, r0)
++			opset(AVMOH, r0)
++			opset(AVMOF, r0)
++			opset(AVMLOB, r0)
++			opset(AVMLOH, r0)
++			opset(AVMLOF, r0)
++			opset(AVMHB, r0)
++			opset(AVMHH, r0)
++			opset(AVMHF, r0)
++			opset(AVMLHB, r0)
++			opset(AVMLHH, r0)
++			opset(AVMLHF, r0)
++			opset(AVMLH, r0)
++			opset(AVMLHW, r0)
++			opset(AVMLF, r0)
++			opset(AVNO, r0)
++			opset(AVO, r0)
++			opset(AVPKH, r0)
++			opset(AVPKF, r0)
++			opset(AVPKG, r0)
++			opset(AVSUMGH, r0)
++			opset(AVSUMGF, r0)
++			opset(AVSUMQF, r0)
++			opset(AVSUMQG, r0)
++			opset(AVSUMB, r0)
++			opset(AVSUMH, r0)
++
++		case AVNOT:
++
++		case AVERLLVG:
++			opset(AVERLLVB, r0)
++			opset(AVERLLVH, r0)
++			opset(AVERLLVF, r0)
++			opset(AVESLVB, r0)
++			opset(AVESLVH, r0)
++			opset(AVESLVF, r0)
++			opset(AVESLVG, r0)
++			opset(AVESRAVB, r0)
++			opset(AVESRAVH, r0)
++			opset(AVESRAVF, r0)
++			opset(AVESRAVG, r0)
++			opset(AVESRLVB, r0)
++			opset(AVESRLVH, r0)
++			opset(AVESRLVF, r0)
++			opset(AVESRLVG, r0)
++			opset(AVFDDB, r0)
++			opset(AWFDDB, r0)
++			opset(AVFSDB, r0)
++			opset(AWFSDB, r0)
++			opset(AVSL, r0)
++			opset(AVSLB, r0)
++			opset(AVSRA, r0)
++			opset(AVSRAB, r0)
++			opset(AVSRL, r0)
++			opset(AVSRLB, r0)
++			opset(AVSF, r0)
++			opset(AVSG, r0)
++			opset(AVSQ, r0)
++			opset(AVSCBIB, r0)
++			opset(AVSCBIH, r0)
++			opset(AVSCBIF, r0)
++			opset(AVSCBIG, r0)
++			opset(AVSCBIQ, r0)
++
++		case AVACQ:
++			opset(AVACCCQ, r0)
++			opset(AVGFMAB, r0)
++			opset(AVGFMAH, r0)
++			opset(AVGFMAF, r0)
++			opset(AVGFMAG, r0)
++			opset(AVMALB, r0)
++			opset(AVMALHW, r0)
++			opset(AVMALF, r0)
++			opset(AVMAHB, r0)
++			opset(AVMAHH, r0)
++			opset(AVMAHF, r0)
++			opset(AVMALHB, r0)
++			opset(AVMALHH, r0)
++			opset(AVMALHF, r0)
++			opset(AVMAEB, r0)
++			opset(AVMAEH, r0)
++			opset(AVMAEF, r0)
++			opset(AVMALEB, r0)
++			opset(AVMALEH, r0)
++			opset(AVMALEF, r0)
++			opset(AVMAOB, r0)
++			opset(AVMAOH, r0)
++			opset(AVMAOF, r0)
++			opset(AVMALOB, r0)
++			opset(AVMALOH, r0)
++			opset(AVMALOF, r0)
++			opset(AVSTRCB, r0)
++			opset(AVSTRCH, r0)
++			opset(AVSTRCF, r0)
++			opset(AVSTRCBS, r0)
++			opset(AVSTRCHS, r0)
++			opset(AVSTRCFS, r0)
++			opset(AVSTRCZB, r0)
++			opset(AVSTRCZH, r0)
++			opset(AVSTRCZF, r0)
++			opset(AVSTRCZBS, r0)
++			opset(AVSTRCZHS, r0)
++			opset(AVSTRCZFS, r0)
++			opset(AVSBCBIQ, r0)
++			opset(AVSBIQ, r0)
++
++		case AVSEL:
++			opset(AVFMADB, r0)
++			opset(AWFMADB, r0)
++			opset(AVFMSDB, r0)
++			opset(AWFMSDB, r0)
++			opset(AVPERM, r0)
++
++		case AVLVGP:
++
 +		case AADD,
 +			AMOVW,
 +			/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
@@ -16315,6 +19489,160 @@ index 0000000..7956f22
 +	OP_XSCH    uint32 = 0xB276 // FORMAT_S          CANCEL SUBCHANNEL
 +	OP_XY      uint32 = 0xE357 // FORMAT_RXY1       EXCLUSIVE OR (32)
 +	OP_ZAP     uint32 = 0xF800 // FORMAT_SS2        ZERO AND ADD
++
++	// added in z13
++	OP_CXPT   uint32 = 0xEDAF // 	RSL-b	CONVERT FROM PACKED (to extended DFP)
++	OP_CDPT   uint32 = 0xEDAE // 	RSL-b	CONVERT FROM PACKED (to long DFP)
++	OP_CPXT   uint32 = 0xEDAD // 	RSL-b	CONVERT TO PACKED (from extended DFP)
++	OP_CPDT   uint32 = 0xEDAC // 	RSL-b	CONVERT TO PACKED (from long DFP)
++	OP_LZRF   uint32 = 0xE33B // 	RXY-a	LOAD AND ZERO RIGHTMOST BYTE (32)
++	OP_LZRG   uint32 = 0xE32A // 	RXY-a	LOAD AND ZERO RIGHTMOST BYTE (64)
++	OP_LCCB   uint32 = 0xE727 // 	RXE	LOAD COUNT TO BLOCK BOUNDARY
++	OP_LOCHHI uint32 = 0xEC4E // 	RIE-g	LOAD HALFWORD HIGH IMMEDIATE ON CONDITION (32←16)
++	OP_LOCHI  uint32 = 0xEC42 // 	RIE-g	LOAD HALFWORD IMMEDIATE ON CONDITION (32←16)
++	OP_LOCGHI uint32 = 0xEC46 // 	RIE-g	LOAD HALFWORD IMMEDIATE ON CONDITION (64←16)
++	OP_LOCFH  uint32 = 0xEBE0 // 	RSY-b	LOAD HIGH ON CONDITION (32)
++	OP_LOCFHR uint32 = 0xB9E0 // 	RRF-c	LOAD HIGH ON CONDITION (32)
++	OP_LLZRGF uint32 = 0xE33A // 	RXY-a	LOAD LOGICAL AND ZERO RIGHTMOST BYTE (64←32)
++	OP_STOCFH uint32 = 0xEBE1 // 	RSY-b	STORE HIGH ON CONDITION
++	OP_VA     uint32 = 0xE7F3 // 	VRR-c	VECTOR ADD
++	OP_VACC   uint32 = 0xE7F1 // 	VRR-c	VECTOR ADD COMPUTE CARRY
++	OP_VAC    uint32 = 0xE7BB // 	VRR-d	VECTOR ADD WITH CARRY
++	OP_VACCC  uint32 = 0xE7B9 // 	VRR-d	VECTOR ADD WITH CARRY COMPUTE CARRY
++	OP_VN     uint32 = 0xE768 // 	VRR-c	VECTOR AND
++	OP_VNC    uint32 = 0xE769 // 	VRR-c	VECTOR AND WITH COMPLEMENT
++	OP_VAVG   uint32 = 0xE7F2 // 	VRR-c	VECTOR AVERAGE
++	OP_VAVGL  uint32 = 0xE7F0 // 	VRR-c	VECTOR AVERAGE LOGICAL
++	OP_VCKSM  uint32 = 0xE766 // 	VRR-c	VECTOR CHECKSUM
++	OP_VCEQ   uint32 = 0xE7F8 // 	VRR-b	VECTOR COMPARE EQUAL
++	OP_VCH    uint32 = 0xE7FB // 	VRR-b	VECTOR COMPARE HIGH
++	OP_VCHL   uint32 = 0xE7F9 // 	VRR-b	VECTOR COMPARE HIGH LOGICAL
++	OP_VCLZ   uint32 = 0xE753 // 	VRR-a	VECTOR COUNT LEADING ZEROS
++	OP_VCTZ   uint32 = 0xE752 // 	VRR-a	VECTOR COUNT TRAILING ZEROS
++	OP_VEC    uint32 = 0xE7DB // 	VRR-a	VECTOR ELEMENT COMPARE
++	OP_VECL   uint32 = 0xE7D9 // 	VRR-a	VECTOR ELEMENT COMPARE LOGICAL
++	OP_VERIM  uint32 = 0xE772 // 	VRI-d	VECTOR ELEMENT ROTATE AND INSERT UNDER MASK
++	OP_VERLL  uint32 = 0xE733 // 	VRS-a	VECTOR ELEMENT ROTATE LEFT LOGICAL
++	OP_VERLLV uint32 = 0xE773 // 	VRR-c	VECTOR ELEMENT ROTATE LEFT LOGICAL
++	OP_VESLV  uint32 = 0xE770 // 	VRR-c	VECTOR ELEMENT SHIFT LEFT
++	OP_VESL   uint32 = 0xE730 // 	VRS-a	VECTOR ELEMENT SHIFT LEFT
++	OP_VESRA  uint32 = 0xE73A // 	VRS-a	VECTOR ELEMENT SHIFT RIGHT ARITHMETIC
++	OP_VESRAV uint32 = 0xE77A // 	VRR-c	VECTOR ELEMENT SHIFT RIGHT ARITHMETIC
++	OP_VESRL  uint32 = 0xE738 // 	VRS-a	VECTOR ELEMENT SHIFT RIGHT LOGICAL
++	OP_VESRLV uint32 = 0xE778 // 	VRR-c	VECTOR ELEMENT SHIFT RIGHT LOGICAL
++	OP_VX     uint32 = 0xE76D // 	VRR-c	VECTOR EXCLUSIVE OR
++	OP_VFAE   uint32 = 0xE782 // 	VRR-b	VECTOR FIND ANY ELEMENT EQUAL
++	OP_VFEE   uint32 = 0xE780 // 	VRR-b	VECTOR FIND ELEMENT EQUAL
++	OP_VFENE  uint32 = 0xE781 // 	VRR-b	VECTOR FIND ELEMENT NOT EQUAL
++	OP_VFA    uint32 = 0xE7E3 // 	VRR-c	VECTOR FP ADD
++	OP_WFK    uint32 = 0xE7CA // 	VRR-a	VECTOR FP COMPARE AND SIGNAL SCALAR
++	OP_VFCE   uint32 = 0xE7E8 // 	VRR-c	VECTOR FP COMPARE EQUAL
++	OP_VFCH   uint32 = 0xE7EB // 	VRR-c	VECTOR FP COMPARE HIGH
++	OP_VFCHE  uint32 = 0xE7EA // 	VRR-c	VECTOR FP COMPARE HIGH OR EQUAL
++	OP_WFC    uint32 = 0xE7CB // 	VRR-a	VECTOR FP COMPARE SCALAR
++	OP_VCDG   uint32 = 0xE7C3 // 	VRR-a	VECTOR FP CONVERT FROM FIXED 64-BIT
++	OP_VCDLG  uint32 = 0xE7C1 // 	VRR-a	VECTOR FP CONVERT FROM LOGICAL 64-BIT
++	OP_VCGD   uint32 = 0xE7C2 // 	VRR-a	VECTOR FP CONVERT TO FIXED 64-BIT
++	OP_VCLGD  uint32 = 0xE7C0 // 	VRR-a	VECTOR FP CONVERT TO LOGICAL 64-BIT
++	OP_VFD    uint32 = 0xE7E5 // 	VRR-c	VECTOR FP DIVIDE
++	OP_VLDE   uint32 = 0xE7C4 // 	VRR-a	VECTOR FP LOAD LENGTHENED
++	OP_VLED   uint32 = 0xE7C5 // 	VRR-a	VECTOR FP LOAD ROUNDED
++	OP_VFM    uint32 = 0xE7E7 // 	VRR-c	VECTOR FP MULTIPLY
++	OP_VFMA   uint32 = 0xE78F // 	VRR-e	VECTOR FP MULTIPLY AND ADD
++	OP_VFMS   uint32 = 0xE78E // 	VRR-e	VECTOR FP MULTIPLY AND SUBTRACT
++	OP_VFPSO  uint32 = 0xE7CC // 	VRR-a	VECTOR FP PERFORM SIGN OPERATION
++	OP_VFSQ   uint32 = 0xE7CE // 	VRR-a	VECTOR FP SQUARE ROOT
++	OP_VFS    uint32 = 0xE7E2 // 	VRR-c	VECTOR FP SUBTRACT
++	OP_VFTCI  uint32 = 0xE74A // 	VRI-e	VECTOR FP TEST DATA CLASS IMMEDIATE
++	OP_VGFM   uint32 = 0xE7B4 // 	VRR-c	VECTOR GALOIS FIELD MULTIPLY SUM
++	OP_VGFMA  uint32 = 0xE7BC // 	VRR-d	VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE
++	OP_VGEF   uint32 = 0xE713 // 	VRV	VECTOR GATHER ELEMENT (32)
++	OP_VGEG   uint32 = 0xE712 // 	VRV	VECTOR GATHER ELEMENT (64)
++	OP_VGBM   uint32 = 0xE744 // 	VRI-a	VECTOR GENERATE BYTE MASK
++	OP_VGM    uint32 = 0xE746 // 	VRI-b	VECTOR GENERATE MASK
++	OP_VISTR  uint32 = 0xE75C // 	VRR-a	VECTOR ISOLATE STRING
++	OP_VL     uint32 = 0xE706 // 	VRX	VECTOR LOAD
++	OP_VLR    uint32 = 0xE756 // 	VRR-a	VECTOR LOAD
++	OP_VLREP  uint32 = 0xE705 // 	VRX	VECTOR LOAD AND REPLICATE
++	OP_VLC    uint32 = 0xE7DE // 	VRR-a	VECTOR LOAD COMPLEMENT
++	OP_VLEH   uint32 = 0xE701 // 	VRX	VECTOR LOAD ELEMENT (16)
++	OP_VLEF   uint32 = 0xE703 // 	VRX	VECTOR LOAD ELEMENT (32)
++	OP_VLEG   uint32 = 0xE702 // 	VRX	VECTOR LOAD ELEMENT (64)
++	OP_VLEB   uint32 = 0xE700 // 	VRX	VECTOR LOAD ELEMENT (8)
++	OP_VLEIH  uint32 = 0xE741 // 	VRI-a	VECTOR LOAD ELEMENT IMMEDIATE (16)
++	OP_VLEIF  uint32 = 0xE743 // 	VRI-a	VECTOR LOAD ELEMENT IMMEDIATE (32)
++	OP_VLEIG  uint32 = 0xE742 // 	VRI-a	VECTOR LOAD ELEMENT IMMEDIATE (64)
++	OP_VLEIB  uint32 = 0xE740 // 	VRI-a	VECTOR LOAD ELEMENT IMMEDIATE (8)
++	OP_VFI    uint32 = 0xE7C7 // 	VRR-a	VECTOR LOAD FP INTEGER
++	OP_VLGV   uint32 = 0xE721 // 	VRS-c	VECTOR LOAD GR FROM VR ELEMENT
++	OP_VLLEZ  uint32 = 0xE704 // 	VRX	VECTOR LOAD LOGICAL ELEMENT AND ZERO
++	OP_VLM    uint32 = 0xE736 // 	VRS-a	VECTOR LOAD MULTIPLE
++	OP_VLP    uint32 = 0xE7DF // 	VRR-a	VECTOR LOAD POSITIVE
++	OP_VLBB   uint32 = 0xE707 // 	VRX	VECTOR LOAD TO BLOCK BOUNDARY
++	OP_VLVG   uint32 = 0xE722 // 	VRS-b	VECTOR LOAD VR ELEMENT FROM GR
++	OP_VLVGP  uint32 = 0xE762 // 	VRR-f	VECTOR LOAD VR FROM GRS DISJOINT
++	OP_VLL    uint32 = 0xE737 // 	VRS-b	VECTOR LOAD WITH LENGTH
++	OP_VMX    uint32 = 0xE7FF // 	VRR-c	VECTOR MAXIMUM
++	OP_VMXL   uint32 = 0xE7FD // 	VRR-c	VECTOR MAXIMUM LOGICAL
++	OP_VMRH   uint32 = 0xE761 // 	VRR-c	VECTOR MERGE HIGH
++	OP_VMRL   uint32 = 0xE760 // 	VRR-c	VECTOR MERGE LOW
++	OP_VMN    uint32 = 0xE7FE // 	VRR-c	VECTOR MINIMUM
++	OP_VMNL   uint32 = 0xE7FC // 	VRR-c	VECTOR MINIMUM LOGICAL
++	OP_VMAE   uint32 = 0xE7AE // 	VRR-d	VECTOR MULTIPLY AND ADD EVEN
++	OP_VMAH   uint32 = 0xE7AB // 	VRR-d	VECTOR MULTIPLY AND ADD HIGH
++	OP_VMALE  uint32 = 0xE7AC // 	VRR-d	VECTOR MULTIPLY AND ADD LOGICAL EVEN
++	OP_VMALH  uint32 = 0xE7A9 // 	VRR-d	VECTOR MULTIPLY AND ADD LOGICAL HIGH
++	OP_VMALO  uint32 = 0xE7AD // 	VRR-d	VECTOR MULTIPLY AND ADD LOGICAL ODD
++	OP_VMAL   uint32 = 0xE7AA // 	VRR-d	VECTOR MULTIPLY AND ADD LOW
++	OP_VMAO   uint32 = 0xE7AF // 	VRR-d	VECTOR MULTIPLY AND ADD ODD
++	OP_VME    uint32 = 0xE7A6 // 	VRR-c	VECTOR MULTIPLY EVEN
++	OP_VMH    uint32 = 0xE7A3 // 	VRR-c	VECTOR MULTIPLY HIGH
++	OP_VMLE   uint32 = 0xE7A4 // 	VRR-c	VECTOR MULTIPLY EVEN LOGICAL
++	OP_VMLH   uint32 = 0xE7A1 // 	VRR-c	VECTOR MULTIPLY HIGH LOGICAL
++	OP_VMLO   uint32 = 0xE7A5 // 	VRR-c	VECTOR MULTIPLY ODD LOGICAL
++	OP_VML    uint32 = 0xE7A2 // 	VRR-c	VECTOR MULTIPLY LOW
++	OP_VMO    uint32 = 0xE7A7 // 	VRR-c	VECTOR MULTIPLY ODD
++	OP_VNO    uint32 = 0xE76B // 	VRR-c	VECTOR NOR
++	OP_VO     uint32 = 0xE76A // 	VRR-c	VECTOR OR
++	OP_VPK    uint32 = 0xE794 // 	VRR-c	VECTOR PACK
++	OP_VPKLS  uint32 = 0xE795 // 	VRR-b	VECTOR PACK LOGICAL SATURATE
++	OP_VPKS   uint32 = 0xE797 // 	VRR-b	VECTOR PACK SATURATE
++	OP_VPERM  uint32 = 0xE78C // 	VRR-e	VECTOR PERMUTE
++	OP_VPDI   uint32 = 0xE784 // 	VRR-c	VECTOR PERMUTE DOUBLEWORD IMMEDIATE
++	OP_VPOPCT uint32 = 0xE750 // 	VRR-a	VECTOR POPULATION COUNT
++	OP_VREP   uint32 = 0xE74D // 	VRI-c	VECTOR REPLICATE
++	OP_VREPI  uint32 = 0xE745 // 	VRI-a	VECTOR REPLICATE IMMEDIATE
++	OP_VSCEF  uint32 = 0xE71B // 	VRV	VECTOR SCATTER ELEMENT (32)
++	OP_VSCEG  uint32 = 0xE71A // 	VRV	VECTOR SCATTER ELEMENT (64)
++	OP_VSEL   uint32 = 0xE78D // 	VRR-e	VECTOR SELECT
++	OP_VSL    uint32 = 0xE774 // 	VRR-c	VECTOR SHIFT LEFT
++	OP_VSLB   uint32 = 0xE775 // 	VRR-c	VECTOR SHIFT LEFT BY BYTE
++	OP_VSLDB  uint32 = 0xE777 // 	VRI-d	VECTOR SHIFT LEFT DOUBLE BY BYTE
++	OP_VSRA   uint32 = 0xE77E // 	VRR-c	VECTOR SHIFT RIGHT ARITHMETIC
++	OP_VSRAB  uint32 = 0xE77F // 	VRR-c	VECTOR SHIFT RIGHT ARITHMETIC BY BYTE
++	OP_VSRL   uint32 = 0xE77C // 	VRR-c	VECTOR SHIFT RIGHT LOGICAL
++	OP_VSRLB  uint32 = 0xE77D // 	VRR-c	VECTOR SHIFT RIGHT LOGICAL BY BYTE
++	OP_VSEG   uint32 = 0xE75F // 	VRR-a	VECTOR SIGN EXTEND TO DOUBLEWORD
++	OP_VST    uint32 = 0xE70E // 	VRX	VECTOR STORE
++	OP_VSTEH  uint32 = 0xE709 // 	VRX	VECTOR STORE ELEMENT (16)
++	OP_VSTEF  uint32 = 0xE70B // 	VRX	VECTOR STORE ELEMENT (32)
++	OP_VSTEG  uint32 = 0xE70A // 	VRX	VECTOR STORE ELEMENT (64)
++	OP_VSTEB  uint32 = 0xE708 // 	VRX	VECTOR STORE ELEMENT (8)
++	OP_VSTM   uint32 = 0xE73E // 	VRS-a	VECTOR STORE MULTIPLE
++	OP_VSTL   uint32 = 0xE73F // 	VRS-b	VECTOR STORE WITH LENGTH
++	OP_VSTRC  uint32 = 0xE78A // 	VRR-d	VECTOR STRING RANGE COMPARE
++	OP_VS     uint32 = 0xE7F7 // 	VRR-c	VECTOR SUBTRACT
++	OP_VSCBI  uint32 = 0xE7F5 // 	VRR-c	VECTOR SUBTRACT COMPUTE BORROW INDICATION
++	OP_VSBCBI uint32 = 0xE7BD // 	VRR-d	VECTOR SUBTRACT WITH BORROW COMPUTE BORROW INDICATION
++	OP_VSBI   uint32 = 0xE7BF // 	VRR-d	VECTOR SUBTRACT WITH BORROW INDICATION
++	OP_VSUMG  uint32 = 0xE765 // 	VRR-c	VECTOR SUM ACROSS DOUBLEWORD
++	OP_VSUMQ  uint32 = 0xE767 // 	VRR-c	VECTOR SUM ACROSS QUADWORD
++	OP_VSUM   uint32 = 0xE764 // 	VRR-c	VECTOR SUM ACROSS WORD
++	OP_VTM    uint32 = 0xE7D8 // 	VRR-a	VECTOR TEST UNDER MASK
++	OP_VUPH   uint32 = 0xE7D7 // 	VRR-a	VECTOR UNPACK HIGH
++	OP_VUPLH  uint32 = 0xE7D5 // 	VRR-a	VECTOR UNPACK LOGICAL HIGH
++	OP_VUPLL  uint32 = 0xE7D4 // 	VRR-a	VECTOR UNPACK LOGICAL LOW
++	OP_VUPL   uint32 = 0xE7D6 // 	VRR-a	VECTOR UNPACK LOW
 +)
 +
 +func oclass(a *obj.Addr) int {
@@ -16334,6 +19662,17 @@ index 0000000..7956f22
 +	return rel
 +}
 +
++func addrilrelocoffset(ctxt *obj.Link, sym *obj.LSym, add, offset int64) *obj.Reloc {
++	offset += int64(2) // relocation offset from start of instruction
++	rel := obj.Addrel(ctxt.Cursym)
++	rel.Off = int32(ctxt.Pc + offset)
++	rel.Siz = 4
++	rel.Sym = sym
++	rel.Add = add + offset + int64(rel.Siz)
++	rel.Type = obj.R_PCRELDBL
++	return rel
++}
++
 +// Add a CALL relocation for the immediate in a RIL style instruction.
 +// The addend will be adjusted as required.
 +func addcallreloc(ctxt *obj.Link, sym *obj.LSym, add int64) *obj.Reloc {
@@ -16601,30 +19940,6 @@ index 0000000..7956f22
 +			RXY(a, OP_LAY, uint32(p.To.Reg), uint32(r), 0, uint32(v), asm)
 +		}
 +
-+	case 4: /* add/mul $scon,[r1],r2 */ //Might have to worry about condition codes
-+		v := regoff(ctxt, &p.From)
-+
-+		r := int(p.To.Reg)
-+		r2 := int(p.Reg)
-+
-+		if p.Reg == 0 && p.To.Reg == 0 {
-+			ctxt.Diag("literal operation on R0\n%v", p)
-+		}
-+		if p.As == AADD {
-+			if r2 == 0 {
-+				RIL(a, OP_AGFI, uint32(r), uint32(v), asm)
-+			} else {
-+				RIE(d, OP_AGHIK, uint32(r), uint32(r2), uint32(v), 0, 0, 0, 0, asm)
-+			}
-+		} else if p.As == AMULLW {
-+			if r2 == 0 {
-+				RIL(a, OP_MSGFI, uint32(r), uint32(v), asm)
-+			} else {
-+				RIL(a, OP_MSGFI, uint32(r2), uint32(v), asm)
-+				RRE(OP_LGFR, uint32(r), uint32(r2), asm)
-+			}
-+		}
-+
 +	case 5: /* syscall */ // This might be right, assuming SVC is the same as Power's SC
 +		I(OP_SVC, 0, asm)
 +
@@ -16921,63 +20236,78 @@ index 0000000..7956f22
 +			addrilreloc(ctxt, p.From.Sym, d)
 +		}
 +
-+	case 20: /* add $ucon,,r */
-+		v := regoff(ctxt, &p.From)
-+
-+		r := int(p.Reg)
-+		if p.As == AADD && p.To.Reg == 0 {
-+			ctxt.Diag("literal operation on R0\n%v", p)
-+		}
-+		if r == 0 {
-+			RIL(a, OP_AGFI, uint32(p.To.Reg), uint32(v), asm)
-+		} else {
-+			RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
-+			RRE(OP_AGR, REGTMP, uint32(r), asm)
-+			RRE(OP_LGR, uint32(p.To.Reg), REGTMP, asm)
-+		}
-+
 +	case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
 +
 +		if p.From.Sym != nil {
 +			ctxt.Diag("%v is not supported", p)
 +		}
 +
-+		d := vregoff(ctxt, &p.From)
-+		var opcode uint32
++		v := vregoff(ctxt, &p.From)
++		r := p.Reg
++		if r == 0 {
++			r = p.To.Reg
++		}
 +		switch p.As {
 +		default:
 +		case AADD:
-+			opcode = OP_AGFI
++			if r == p.To.Reg {
++				RIL(a, OP_AGFI, uint32(p.To.Reg), uint32(v), asm)
++			} else if int64(int16(v)) == v {
++				RIE(d, OP_AGHIK, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm)
++			} else {
++				RRE(OP_LGR, uint32(p.To.Reg), uint32(r), asm)
++				RIL(a, OP_AGFI, uint32(p.To.Reg), uint32(v), asm)
++			}
 +		case AADDC:
-+			opcode = OP_ALGFI
++			if r != p.To.Reg {
++				RRE(OP_LGR, uint32(p.To.Reg), uint32(r), asm)
++			}
++			RIL(a, OP_ALGFI, uint32(p.To.Reg), uint32(v), asm)
 +		case AMULLW:
-+			opcode = OP_MSGFI
-+		}
-+
-+		r := int(p.Reg)
-+		if r != 0 {
-+			RRE(OP_LGR, uint32(p.To.Reg), uint32(r), asm)
++			if r != p.To.Reg {
++				RRE(OP_LGR, uint32(p.To.Reg), uint32(r), asm)
++			}
++			RIL(a, OP_MSGFI, uint32(p.To.Reg), uint32(v), asm)
 +		}
-+		RIL(a, opcode, uint32(p.To.Reg), uint32(d), asm)
 +
 +	case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
 +
-+		d := regoff(ctxt, &p.From)
++		v := vregoff(ctxt, &p.From)
 +		var opcode uint32
-+		r := int(p.Reg)
++		r := p.Reg
 +		if r == 0 {
++			r = p.To.Reg
++		}
++		if r == p.To.Reg {
 +			switch p.As {
 +			default:
 +				ctxt.Diag("%v is not supported", p)
 +			case AAND:
-+				opcode = OP_NGR
++				if v >= 0 { // needs zero extend
++					RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
++					RRE(OP_NGR, uint32(p.To.Reg), REGTMP, asm)
++				} else if int64(int16(v)) == v {
++					RI(OP_NILL, uint32(p.To.Reg), uint32(v), asm)
++				} else { //  r.To.Reg & 0xffffffff00000000 & uint32(v)
++					RIL(a, OP_NILF, uint32(p.To.Reg), uint32(v), asm)
++				}
 +			case AOR:
-+				opcode = OP_OGR
++				if int64(uint32(v)) != v { // needs sign extend
++					RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
++					RRE(OP_OGR, uint32(p.To.Reg), REGTMP, asm)
++				} else if int64(uint16(v)) == v {
++					RI(OP_OILL, uint32(p.To.Reg), uint32(v), asm)
++				} else {
++					RIL(a, OP_OILF, uint32(p.To.Reg), uint32(v), asm)
++				}
 +			case AXOR:
-+				opcode = OP_XGR
++				if int64(uint32(v)) != v { // needs sign extend
++					RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
++					RRE(OP_XGR, uint32(p.To.Reg), REGTMP, asm)
++				} else {
++					RIL(a, OP_XILF, uint32(p.To.Reg), uint32(v), asm)
++				}
 +			}
-+			RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
-+			RRE(opcode, uint32(p.To.Reg), REGTMP, asm)
 +		} else {
 +			switch p.As {
 +			default:
@@ -16989,7 +20319,7 @@ index 0000000..7956f22
 +			case AXOR:
 +				opcode = OP_XGRK
 +			}
-+			RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
++			RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
 +			RRF(opcode, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
 +		}
 +
@@ -17166,7 +20496,7 @@ index 0000000..7956f22
 +				opcode = OP_LNDBR
 +			case AFNEG:
 +				opcode = OP_LCDFR
-+			case AFRSP:
++			case ALEDBR:
 +				opcode = OP_LEDBR
 +			case ALDEBR:
 +				opcode = OP_LDEBR
@@ -17400,66 +20730,6 @@ index 0000000..7956f22
 +			RSY(OP_SRLK, uint32(p.To.Reg), uint32(r), 0, uint32(v), asm)
 +		}
 +
-+	case 58: /* logical $andcon,[s],a */
-+		d := regoff(ctxt, &p.From)
-+
-+		switch p.As {
-+		case AAND, AOR, AXOR:
-+			var opcode1, opcode2 uint32
-+			switch p.As {
-+			default:
-+				ctxt.Diag("%v is not supported", p)
-+			case AAND:
-+				opcode1 = OP_NGR
-+				opcode2 = OP_NGRK
-+			case AOR:
-+				opcode1 = OP_OGR
-+				opcode2 = OP_OGRK
-+			case AXOR:
-+				opcode1 = OP_XGR
-+				opcode2 = OP_XGRK
-+			}
-+
-+			r := int(p.Reg)
-+			if r == 0 {
-+				RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
-+				RRE(opcode1, uint32(p.To.Reg), REGTMP, asm)
-+			} else {
-+				RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
-+				RRF(opcode2, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
-+			}
-+		}
-+
-+	case 59: /* or/and $ucon,,r */
-+		d := regoff(ctxt, &p.From)
-+
-+		switch p.As {
-+		case AAND, AOR, AXOR:
-+			var opcode1, opcode2 uint32
-+			switch p.As {
-+			default:
-+				ctxt.Diag("%v is not supported", p)
-+			case AAND:
-+				opcode1 = OP_NGR
-+				opcode2 = OP_NGRK
-+			case AOR:
-+				opcode1 = OP_OGR
-+				opcode2 = OP_OGRK
-+			case AXOR:
-+				opcode1 = OP_XGR
-+				opcode2 = OP_XGRK
-+			}
-+
-+			r := int(p.Reg)
-+			if r == 0 {
-+				RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
-+				RRE(opcode1, uint32(p.To.Reg), REGTMP, asm)
-+			} else {
-+				RIL(a, OP_LGFI, REGTMP, uint32(d), asm)
-+				RRF(opcode2, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
-+			}
-+		}
-+
 +	case 62: /* rlwmi $sh,s,$mask,a */
 +		v := regoff(ctxt, &p.From)
 +		d := vregoff(ctxt, p.From3)
@@ -17547,6 +20817,101 @@ index 0000000..7956f22
 +		}
 +		RIL(0, uint32(zopril(ctxt, int(p.As))), uint32(p.From.Reg), uint32(int32(regoff(ctxt, &p.To))), asm)
 +
++	case 72: // MOV int32 -> s+o(r)(i*1)
++		v := regoff(ctxt, &p.From)
++		d := regoff(ctxt, &p.To)
++		r := p.To.Reg
++		x := p.To.Index
++		if r == 0 {
++			r = o.param
++		}
++		if p.From.Sym != nil {
++			RIL(b, OP_LARL, REGTMP, 0, asm)
++			if v&0x1 != 0 {
++				v -= 1
++				RX(OP_LA, uint32(REGTMP), uint32(REGTMP), 0, 1, asm)
++			}
++			addrilreloc(ctxt, p.From.Sym, int64(v))
++			if d < -DISP20/2 || d >= DISP20/2 {
++				RIL(a, OP_LGFI, REGTMP2, uint32(d), asm)
++				if x != 0 {
++					RRE(OP_AGR, REGTMP2, uint32(x), asm)
++				}
++				d = 0
++				x = REGTMP2
++			}
++			RXY(0, zopstore(ctxt, int(p.As)), REGTMP, uint32(x), uint32(r), uint32(d), asm)
++		} else if int32(int16(v)) == v && x == 0 && d >= 0 && d < DISP12 {
++			var opcode uint32
++			switch p.As {
++			case AMOVD:
++				opcode = OP_MVGHI
++			case AMOVW, AMOVWZ:
++				opcode = OP_MVHI
++			case AMOVH, AMOVHZ:
++				opcode = OP_MVHHI
++			case AMOVB, AMOVBZ:
++				opcode = OP_MVI
++			}
++			if opcode == OP_MVI {
++				SI(opcode, uint32(v), uint32(r), uint32(d), asm)
++			} else {
++				SIL(opcode, uint32(r), uint32(d), uint32(v), asm)
++			}
++		} else {
++			RIL(a, OP_LGFI, REGTMP, uint32(v), asm)
++			if d < -DISP20/2 || d >= DISP20/2 {
++				RIL(a, OP_LGFI, REGTMP2, uint32(d), asm)
++				if x != 0 {
++					RRE(OP_AGR, REGTMP2, uint32(x), asm)
++				}
++				d = 0
++				x = REGTMP2
++			}
++			RXY(0, zopstore(ctxt, int(p.As)), REGTMP, uint32(x), uint32(r), uint32(d), asm)
++		}
++
++	case 73: // MOV int32 -> addr
++		v := regoff(ctxt, &p.From)
++		d := regoff(ctxt, &p.To)
++		a := uint32(0)
++		if d&1 != 0 {
++			d -= 1
++			a = 1
++		}
++		RIL(b, OP_LARL, REGTMP, uint32(d), asm)
++		addrilreloc(ctxt, p.To.Sym, int64(d))
++		if p.From.Sym != nil {
++			RIL(b, OP_LARL, REGTMP2, 0, asm)
++			a := uint32(0)
++			if v&0x1 != 0 {
++				v -= 1
++				RX(OP_LA, uint32(REGTMP2), uint32(REGTMP2), 0, 1, asm)
++			}
++			addrilrelocoffset(ctxt, p.From.Sym, int64(v), FORMAT_RIL_size)
++			RXY(0, zopstore(ctxt, int(p.As)), REGTMP2, 0, REGTMP, a, asm)
++		} else if int32(int16(v)) == v {
++			var opcode uint32
++			switch p.As {
++			case AMOVD:
++				opcode = OP_MVGHI
++			case AMOVW, AMOVWZ:
++				opcode = OP_MVHI
++			case AMOVH, AMOVHZ:
++				opcode = OP_MVHHI
++			case AMOVB, AMOVBZ:
++				opcode = OP_MVI
++			}
++			if opcode == OP_MVI {
++				SI(opcode, uint32(v), uint32(REGTMP), a, asm)
++			} else {
++				SIL(opcode, uint32(REGTMP), a, uint32(v), asm)
++			}
++		} else {
++			RIL(a, OP_LGFI, REGTMP2, uint32(v), asm)
++			RXY(0, zopstore(ctxt, int(p.As)), REGTMP2, 0, REGTMP, a, asm)
++		}
++
 +	/* relocation operations */
 +	case 74: /* AMOV[F][D|W|H|B|S][Z] Rs, addr -> ST[G|H]RL Rs, addr (with a reloaction entry ) */
 +		v := regoff(ctxt, &p.To)
@@ -17714,11 +21079,13 @@ index 0000000..7956f22
 +
 +	case 84: /* storage-and-storage operations (mvc, clc, xc, oc, nc) */
 +		l := regoff(ctxt, p.From3)
-+		d2 := regoff(ctxt, &p.From)
 +		d1 := regoff(ctxt, &p.To)
++		d2 := regoff(ctxt, &p.From)
 +		if l < 1 || l > 256 {
 +			ctxt.Diag("number of bytes (%v) not in range [1,256]", l)
 +		}
++		b1 := p.To.Reg
++		b2 := p.From.Reg
 +		var opcode uint32
 +		switch p.As {
 +		default:
@@ -17727,6 +21094,9 @@ index 0000000..7956f22
 +			opcode = OP_MVC
 +		case ACLC:
 +			opcode = OP_CLC
++			// swap operand order for CLC so that it matches CMP
++			b1, b2 = b2, b1
++			d1, d2 = d2, d1
 +		case AXC:
 +			opcode = OP_XC
 +		case AOC:
@@ -17734,7 +21104,7 @@ index 0000000..7956f22
 +		case ANC:
 +			opcode = OP_NC
 +		}
-+		SS(a, opcode, uint32(l-1), 0, uint32(p.To.Reg), uint32(d1), uint32(p.From.Reg), uint32(d2), asm)
++		SS(a, opcode, uint32(l-1), 0, uint32(b1), uint32(d1), uint32(b2), uint32(d2), asm)
 +
 +	case 85: /* larl: load address relative long */
 +		// When using larl directly, don't add a nop
@@ -17750,12 +21120,17 @@ index 0000000..7956f22
 +		RIL(b, OP_LARL, uint32(p.To.Reg), uint32(v>>1), asm)
 +
 +	case 86: /* lay?: load address */
-+		v := vregoff(ctxt, &p.From)
++		d := vregoff(ctxt, &p.From)
++		x := p.From.Index
++		b := p.From.Reg
++		if b == 0 {
++			b = o.param
++		}
 +		switch p.As {
 +		case ALA:
-+			RX(OP_LA, uint32(p.To.Reg), uint32(p.From.Reg), 0, uint32(v), asm)
++			RX(OP_LA, uint32(p.To.Reg), uint32(x), uint32(b), uint32(d), asm)
 +		case ALAY:
-+			RXY(0, OP_LAY, uint32(p.To.Reg), uint32(p.From.Reg), 0, uint32(v), asm)
++			RXY(0, OP_LAY, uint32(p.To.Reg), uint32(x), uint32(b), uint32(d), asm)
 +		}
 +
 +	case 87: /* exrl: execute relative long */
@@ -17790,11 +21165,10 @@ index 0000000..7956f22
 +		S(opcode, uint32(r), uint32(v), asm)
 +
 +	case 89:
-+		if p.Pcond == nil {
-+			ctxt.Diag("no branch target")
-+			break
++		var v int32
++		if p.Pcond != nil {
++			v = int32((p.Pcond.Pc - p.Pc) >> 1)
 +		}
-+		v := int32((p.Pcond.Pc - p.Pc) >> 1)
 +		var opcode, opcode2 uint32
 +		switch p.As {
 +		case ACMPBEQ, ACMPBGE, ACMPBGT, ACMPBLE, ACMPBLT, ACMPBNE:
@@ -17813,9 +21187,9 @@ index 0000000..7956f22
 +		}
 +
 +	case 90:
-+		if p.Pcond == nil {
-+			ctxt.Diag("no branch target")
-+			break
++		var v int32
++		if p.Pcond != nil {
++			v = int32((p.Pcond.Pc - p.Pc) >> 1)
 +		}
 +		var opcode, opcode2 uint32
 +		switch p.As {
@@ -17826,7 +21200,6 @@ index 0000000..7956f22
 +			opcode = OP_CLGIJ
 +			opcode2 = OP_CLGFI
 +		}
-+		v := int32((p.Pcond.Pc - p.Pc) >> 1)
 +		mask := branchMask(ctxt, p)
 +		if int32(int16(v)) != v {
 +			RIL(0, opcode2, uint32(p.From.Reg), uint32(int32(regoff(ctxt, p.From3))), asm)
@@ -17835,26 +21208,6 @@ index 0000000..7956f22
 +			RIE(c, opcode, uint32(p.From.Reg), mask, uint32(v), 0, 0, 0, uint32(int32(regoff(ctxt, p.From3))), asm)
 +		}
 +
-+	case 92:
-+		var opcode uint32
-+		switch p.As {
-+		case AMOVD:
-+			opcode = OP_MVGHI
-+		case AMOVW, AMOVWZ:
-+			opcode = OP_MVHI
-+		case AMOVH, AMOVHZ:
-+			opcode = OP_MVHHI
-+		case AMOVB, AMOVBZ:
-+			opcode = OP_MVI
-+		}
-+		v := regoff(ctxt, &p.From)
-+		d := regoff(ctxt, &p.To)
-+		if opcode == OP_MVI {
-+			SI(opcode, uint32(v), uint32(p.To.Reg), uint32(d), asm)
-+		} else {
-+			SIL(opcode, uint32(p.To.Reg), uint32(d), uint32(v), asm)
-+		}
-+
 +	case 93: // GOT lookup
 +		v := vregoff(ctxt, &p.To)
 +		if v != 0 {
@@ -17904,8 +21257,291 @@ index 0000000..7956f22
 +		RXY(0, OP_LGF, uint32(p.To.Reg), REGTMP, 0, 0, asm)
 +		// TODO(mundaym): add R_390_TLS_LOAD relocation here
 +		// not strictly required but might allow the linker to optimize
-+	}
-+}
++
++	case 96: // CLEAR macro
++		length := vregoff(ctxt, &p.From)
++		offset := vregoff(ctxt, &p.To)
++		reg := p.To.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		if length <= 0 {
++			ctxt.Diag("cannot CLEAR %d bytes, must be greater than 0", length)
++		}
++		for length > 0 {
++			if offset < 0 || offset >= DISP12 {
++				if offset >= -DISP20/2 && offset < DISP20/2 {
++					RXY(0, OP_LAY, uint32(REGTMP), uint32(reg), 0, uint32(offset), asm)
++				} else {
++					if reg != REGTMP {
++						RRE(OP_LGR, uint32(REGTMP), uint32(reg), asm)
++					}
++					RIL(a, OP_AGFI, uint32(REGTMP), uint32(offset), asm)
++				}
++				reg = REGTMP
++				offset = 0
++			}
++			size := length
++			if size > 256 {
++				size = 256
++			}
++
++			switch size {
++			case 1:
++				SI(OP_MVI, 0, uint32(reg), uint32(offset), asm)
++			case 2:
++				SIL(OP_MVHHI, uint32(reg), uint32(offset), 0, asm)
++			case 4:
++				SIL(OP_MVHI, uint32(reg), uint32(offset), 0, asm)
++			case 8:
++				SIL(OP_MVGHI, uint32(reg), uint32(offset), 0, asm)
++			default:
++				SS(a, OP_XC, uint32(size-1), 0, uint32(reg), uint32(offset), uint32(reg), uint32(offset), asm)
++			}
++
++			length -= size
++			offset += size
++		}
++
++	case 97: // STORE MULTIPLE (STMG/STMY)
++		rstart := p.From.Reg
++		rend := p.Reg
++		offset := vregoff(ctxt, &p.To)
++		reg := p.To.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		if offset < -DISP20/2 || offset >= DISP20/2 {
++			if reg != REGTMP {
++				RRE(OP_LGR, uint32(REGTMP), uint32(reg), asm)
++			}
++			RIL(a, OP_AGFI, uint32(REGTMP), uint32(offset), asm)
++			reg = REGTMP
++		}
++		switch p.As {
++		case ASTMY:
++			if offset >= 0 && offset < DISP12 {
++				RS(OP_STM, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++			} else {
++				RSY(OP_STMY, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++			}
++		case ASTMG:
++			RSY(OP_STMG, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++		}
++
++	case 98: // LOAD MULTIPLE (LMG/LMY)
++		rstart := p.Reg
++		rend := p.To.Reg
++		offset := vregoff(ctxt, &p.From)
++		reg := p.From.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		if offset < -DISP20/2 || offset >= DISP20/2 {
++			if reg != REGTMP {
++				RRE(OP_LGR, uint32(REGTMP), uint32(reg), asm)
++			}
++			RIL(a, OP_AGFI, uint32(REGTMP), uint32(offset), asm)
++			reg = REGTMP
++		}
++		switch p.As {
++		case ALMY:
++			if offset >= 0 && offset < DISP12 {
++				RS(OP_LM, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++			} else {
++				RSY(OP_LMY, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++			}
++		case ALMG:
++			RSY(OP_LMG, uint32(rstart), uint32(rend), uint32(reg), uint32(offset), asm)
++		}
++
++	case 100: // VRX STORE
++		op, m3, _ := vop(p.As)
++		if p.From3 != nil {
++			m3 = uint32(vregoff(ctxt, p.From3))
++		}
++		b2 := p.To.Reg
++		if b2 == 0 {
++			b2 = o.param
++		}
++		d2 := uint32(vregoff(ctxt, &p.To))
++		vrx(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm)
++
++	case 101: // VRX LOAD
++		op, m3, _ := vop(p.As)
++		if p.From3 != nil {
++			m3 = uint32(vregoff(ctxt, p.From3))
++		}
++		b2 := p.From.Reg
++		if b2 == 0 {
++			b2 = o.param
++		}
++		d2 := uint32(vregoff(ctxt, &p.From))
++		vrx(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm)
++
++	case 102: // VRV SCATTER
++		op, m3, _ := vop(p.As)
++		if p.From3 != nil {
++			m3 = uint32(vregoff(ctxt, p.From3))
++		}
++		b2 := p.To.Reg
++		if b2 == 0 {
++			b2 = o.param
++		}
++		d2 := uint32(vregoff(ctxt, &p.To))
++		vrv(op, uint32(p.From.Reg), uint32(p.To.Index), uint32(b2), d2, m3, asm)
++
++	case 103: // VRV GATHER
++		op, m3, _ := vop(p.As)
++		if p.From3 != nil {
++			m3 = uint32(vregoff(ctxt, p.From3))
++		}
++		b2 := p.From.Reg
++		if b2 == 0 {
++			b2 = o.param
++		}
++		d2 := uint32(vregoff(ctxt, &p.From))
++		vrv(op, uint32(p.To.Reg), uint32(p.From.Index), uint32(b2), d2, m3, asm)
++
++	case 104: // VRS SHIFT/ROTATE and LOAD GR FROM VR ELEMENT
++		op, m4, _ := vop(p.As)
++		fr := p.Reg
++		if fr == 0 {
++			fr = p.To.Reg
++		}
++		bits := uint32(vregoff(ctxt, &p.From))
++		vrs(op, uint32(p.To.Reg), uint32(fr), uint32(p.From.Reg), bits, m4, asm)
++
++	case 105: // VRS STORE MULTIPLE
++		op, _, _ := vop(p.As)
++		offset := uint32(vregoff(ctxt, &p.To))
++		reg := p.To.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		vrs(op, uint32(p.From.Reg), uint32(p.Reg), uint32(reg), offset, 0, asm)
++
++	case 106: // VRS LOAD MULTIPLE
++		op, _, _ := vop(p.As)
++		offset := uint32(vregoff(ctxt, &p.From))
++		reg := p.From.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		vrs(op, uint32(p.Reg), uint32(p.To.Reg), uint32(reg), offset, 0, asm)
++
++	case 107: // VRS STORE WITH LENGTH
++		op, _, _ := vop(p.As)
++		offset := uint32(vregoff(ctxt, &p.To))
++		reg := p.To.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		vrs(op, uint32(p.From.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm)
++
++	case 108: // VRS LOAD WITH LENGTH
++		op, _, _ := vop(p.As)
++		offset := uint32(vregoff(ctxt, &p.From))
++		reg := p.From.Reg
++		if reg == 0 {
++			reg = o.param
++		}
++		vrs(op, uint32(p.To.Reg), uint32(p.From3.Reg), uint32(reg), offset, 0, asm)
++
++	case 109: // VRI-a instructions
++		op, _, _ := vop(p.As)
++		i2 := uint32(vregoff(ctxt, &p.From))
++		switch p.As {
++		case AVZERO:
++			i2 = 0
++		case AVONE:
++			i2 = 0xffff
++		}
++		m3 := uint32(0)
++		if p.From3 != nil {
++			m3 = uint32(vregoff(ctxt, p.From3))
++		}
++		vria(op, uint32(p.To.Reg), i2, m3, asm)
++
++	case 110:
++		op, m4, _ := vop(p.As)
++		i2 := uint32(vregoff(ctxt, p.From3))
++		i3 := uint32(vregoff(ctxt, &p.From))
++		vrib(op, uint32(p.To.Reg), i2, i3, m4, asm)
++
++	case 111:
++		op, m4, _ := vop(p.As)
++		i2 := uint32(vregoff(ctxt, &p.From))
++		vric(op, uint32(p.To.Reg), uint32(p.Reg), i2, m4, asm)
++
++	case 112:
++		op, m5, _ := vop(p.As)
++		i4 := uint32(vregoff(ctxt, p.From3))
++		vrid(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), i4, m5, asm)
++
++	case 113:
++		op, m4, _ := vop(p.As)
++		m5 := singleElementMask(p.As)
++		i3 := uint32(vregoff(ctxt, &p.From))
++		vrie(op, uint32(p.To.Reg), uint32(p.Reg), i3, m5, m4, asm)
++
++	case 114: // VRR-a
++		op, m3, m5 := vop(p.As)
++		m4 := singleElementMask(p.As)
++		vrra(op, uint32(p.To.Reg), uint32(p.From.Reg), m5, m4, m3, asm)
++
++	case 115: // VRR-a COMPARE
++		op, m3, m5 := vop(p.As)
++		m4 := singleElementMask(p.As)
++		vrra(op, uint32(p.From.Reg), uint32(p.To.Reg), m5, m4, m3, asm)
++
++	case 116: // VRR-a
++
++	case 117: // VRR-b
++		op, m4, m5 := vop(p.As)
++		vrrb(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), m5, m4, asm)
++
++	case 118: // VRR-c
++		op, m4, m6 := vop(p.As)
++		m5 := singleElementMask(p.As)
++		v3 := p.Reg
++		if v3 == 0 {
++			v3 = p.To.Reg
++		}
++		vrrc(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(v3), m6, m5, m4, asm)
++
++	case 119: // VRR-c SHIFT/ROTATE/DIVIDE/SUB (rhs value on the left, like SLD, DIV etc.)
++		op, m4, m6 := vop(p.As)
++		m5 := singleElementMask(p.As)
++		v2 := p.Reg
++		if v2 == 0 {
++			v2 = p.To.Reg
++		}
++		vrrc(op, uint32(p.To.Reg), uint32(v2), uint32(p.From.Reg), m6, m5, m4, asm)
++
++	case 120: // VRR-d
++		op, m6, _ := vop(p.As)
++		m5 := singleElementMask(p.As)
++		v1 := uint32(p.To.Reg)
++		v2 := uint32(p.From3.Reg)
++		v3 := uint32(p.From.Reg)
++		v4 := uint32(p.Reg)
++		vrrd(op, v1, v2, v3, m6, m5, v4, asm)
++
++	case 121: // VRR-e
++		op, m6, _ := vop(p.As)
++		m5 := singleElementMask(p.As)
++		v1 := uint32(p.To.Reg)
++		v2 := uint32(p.From3.Reg)
++		v3 := uint32(p.From.Reg)
++		v4 := uint32(p.Reg)
++		vrre(op, v1, v2, v3, m5, m6, v4, asm)
++
++	case 122: // VRR-f LOAD VRS FROM GRS DISJOINT
++		op, _, _ := vop(p.As)
++		vrrf(op, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), asm)
++	}
++}
 +
 +func vregoff(ctxt *obj.Link, a *obj.Addr) int64 {
 +	ctxt.Instoffset = 0
@@ -18397,12 +22033,169 @@ index 0000000..7956f22
 +		(uint8(b2)<<4)|uint8((d2>>8)&0x0F),
 +		uint8(d2))
 +}
++
++func rxb(va, vb, vc, vd uint32) uint8 {
++	mask := uint8(0)
++	if va >= REG_V16 && va <= REG_V31 {
++		mask |= 0x8
++	}
++	if vb >= REG_V16 && vb <= REG_V31 {
++		mask |= 0x4
++	}
++	if vc >= REG_V16 && vc <= REG_V31 {
++		mask |= 0x2
++	}
++	if vd >= REG_V16 && vd <= REG_V31 {
++		mask |= 0x1
++	}
++	return mask
++}
++
++func vrx(op, v1, x2, b2, d2, m3 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(x2)&0xf),
++		(uint8(b2)<<4)|(uint8(d2>>8)&0xf),
++		uint8(d2),
++		(uint8(m3)<<4)|rxb(v1, 0, 0, 0),
++		uint8(op))
++}
++
++func vrv(op, v1, v2, b2, d2, m3 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		(uint8(b2)<<4)|(uint8(d2>>8)&0xf),
++		uint8(d2),
++		(uint8(m3)<<4)|rxb(v1, v2, 0, 0),
++		uint8(op))
++}
++
++func vrs(op, v1, v3_r3, b2, d2, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v3_r3)&0xf),
++		(uint8(b2)<<4)|(uint8(d2>>8)&0xf),
++		uint8(d2),
++		(uint8(m4)<<4)|rxb(v1, v3_r3, 0, 0),
++		uint8(op))
++}
++
++func vrra(op, v1, v2, m5, m4, m3 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		0,
++		(uint8(m5)<<4)|(uint8(m4)&0xf),
++		(uint8(m3)<<4)|rxb(v1, v2, 0, 0),
++		uint8(op))
++}
++
++func vrrb(op, v1, v2, v3, m5, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		uint8(v3)<<4,
++		uint8(m5)<<4,
++		(uint8(m4)<<4)|rxb(v1, v2, v3, 0),
++		uint8(op))
++}
++
++func vrrc(op, v1, v2, v3, m6, m5, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		uint8(v3)<<4,
++		(uint8(m6)<<4)|(uint8(m5)&0xf),
++		(uint8(m4)<<4)|rxb(v1, v2, v3, 0),
++		uint8(op))
++}
++
++func vrrd(op, v1, v2, v3, m5, m6, v4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		(uint8(v3)<<4)|(uint8(m5)&0xf),
++		uint8(m6)<<4,
++		(uint8(v4)<<4)|rxb(v1, v2, v3, v4),
++		uint8(op))
++}
++
++func vrre(op, v1, v2, v3, m6, m5, v4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		(uint8(v3)<<4)|(uint8(m6)&0xf),
++		uint8(m5),
++		(uint8(v4)<<4)|rxb(v1, v2, v3, v4),
++		uint8(op))
++}
++
++func vrrf(op, v1, r2, r3 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(r2)&0xf),
++		uint8(r3)<<4,
++		0,
++		rxb(v1, 0, 0, 0),
++		uint8(op))
++}
++
++func vria(op, v1, i2, m3 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		uint8(v1)<<4,
++		uint8(i2>>8),
++		uint8(i2),
++		(uint8(m3)<<4)|rxb(v1, 0, 0, 0),
++		uint8(op))
++}
++
++func vrib(op, v1, i2, i3, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		uint8(v1)<<4,
++		uint8(i2),
++		uint8(i3),
++		(uint8(m4)<<4)|rxb(v1, 0, 0, 0),
++		uint8(op))
++}
++
++func vric(op, v1, v3, i2, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v3)&0xf),
++		uint8(i2>>8),
++		uint8(i2),
++		(uint8(m4)<<4)|rxb(v1, v3, 0, 0),
++		uint8(op))
++}
++
++func vrid(op, v1, v2, v3, i4, m5 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		uint8(v3)<<4,
++		uint8(i4),
++		(uint8(m5)<<4)|rxb(v1, v2, v3, 0),
++		uint8(op))
++}
++
++func vrie(op, v1, v2, i3, m5, m4 uint32, asm *[]byte) {
++	*asm = append(*asm,
++		uint8(op>>8),
++		(uint8(v1)<<4)|(uint8(v2)&0xf),
++		uint8(i3>>4),
++		(uint8(i3)<<4)|(uint8(m5)&0xf),
++		(uint8(m4)<<4)|rxb(v1, v2, 0, 0),
++		uint8(op))
++}
 diff --git a/src/cmd/internal/obj/s390x/listz.go b/src/cmd/internal/obj/s390x/listz.go
 new file mode 100644
-index 0000000..c6cb48f
+index 0000000..99702c9
 --- /dev/null
 +++ b/src/cmd/internal/obj/s390x/listz.go
-@@ -0,0 +1,70 @@
+@@ -0,0 +1,73 @@
 +// Based on cmd/internal/obj/ppc64/list9.go.
 +//
 +//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
@@ -18461,6 +22254,9 @@ index 0000000..c6cb48f
 +	if REG_AR0 <= r && r <= REG_AR15 {
 +		return fmt.Sprintf("AR%d", r-REG_AR0)
 +	}
++	if REG_V0 <= r && r <= REG_V31 {
++		return fmt.Sprintf("V%d", r-REG_V0)
++	}
 +	return fmt.Sprintf("Rgok(%d)", r-obj.RBaseS390X)
 +}
 +
@@ -18475,10 +22271,10 @@ index 0000000..c6cb48f
 +}
 diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go
 new file mode 100644
-index 0000000..71c6fb5
+index 0000000..1beb068
 --- /dev/null
 +++ b/src/cmd/internal/obj/s390x/objz.go
-@@ -0,0 +1,990 @@
+@@ -0,0 +1,1014 @@
 +// Based on cmd/internal/obj/ppc64/obj9.go.
 +//
 +//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
@@ -18756,17 +22552,15 @@ index 0000000..71c6fb5
 +			AFDIV,
 +			AFMADD,
 +			AFMOVD,
-+			/* case AFMOVDS: */
 +			AFMOVS,
-+
-+			/* case AFMOVSD: */
 +			AFMSUB,
 +			AFMUL,
 +			AFNABS,
 +			AFNEG,
 +			AFNMADD,
 +			AFNMSUB,
-+			AFRSP,
++			ALEDBR,
++			ALDEBR,
 +			AFSUB:
 +			q = p
 +
@@ -18851,7 +22645,12 @@ index 0000000..71c6fb5
 +	var o int
 +	var p1 *obj.Prog
 +	var p2 *obj.Prog
++	var pLast *obj.Prog
++	var pPre *obj.Prog
++	var pPreempt *obj.Prog
++	wasSplit := false
 +	for p := cursym.Text; p != nil; p = p.Link {
++		pLast = p
 +		o = int(p.As)
 +		switch o {
 +		case obj.ATEXT:
@@ -18873,14 +22672,17 @@ index 0000000..71c6fb5
 +			q = p
 +
 +			if p.From3.Offset&obj.NOSPLIT == 0 {
-+				p = stacksplit(ctxt, p, autosize) // emit split check
++				p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check
++				pPre = p
++				wasSplit = true //need post part of split
 +			}
 +
 +			if autosize != 0 {
 +				q = obj.Appendp(ctxt, p)
-+				q.As = AADD
-+				q.From.Type = obj.TYPE_CONST
++				q.As = AMOVD
++				q.From.Type = obj.TYPE_ADDR
 +				q.From.Offset = int64(-autosize)
++				q.From.Reg = REGSP // not actually needed - REGSP is assumed if no reg is provided
 +				q.To.Type = obj.TYPE_REG
 +				q.To.Reg = REGSP
 +				q.Spadj = autosize
@@ -19072,6 +22874,9 @@ index 0000000..71c6fb5
 +			}
 +		}
 +	}
++	if wasSplit {
++		pLast = stacksplitPost(ctxt, pLast, pPre, pPreempt) // emit post part of split check
++	}
 +}
 +
 +/*
@@ -19119,7 +22924,9 @@ index 0000000..71c6fb5
 +		q = p;
 +	}
 +*/
-+func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
++func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) {
++	var q *obj.Prog
++
 +	// MOVD	g_stackguard(g), R3
 +	p = obj.Appendp(ctxt, p)
 +
@@ -19133,17 +22940,35 @@ index 0000000..71c6fb5
 +	p.To.Type = obj.TYPE_REG
 +	p.To.Reg = REG_R3
 +
-+	var q *obj.Prog
++	q = nil
 +	if framesize <= obj.StackSmall {
 +		// small stack: SP < stackguard
 +		//	CMP	stackguard, SP
-+		p = obj.Appendp(ctxt, p)
 +
-+		p.As = ACMPU
++		//p.To.Type = obj.TYPE_REG
++		//p.To.Reg = REGSP
++
++		// q1: BLT	done
++
++		p = obj.Appendp(ctxt, p)
++		//q1 = p
 +		p.From.Type = obj.TYPE_REG
 +		p.From.Reg = REG_R3
-+		p.To.Type = obj.TYPE_REG
-+		p.To.Reg = REGSP
++		p.Reg = REGSP
++		p.As = ACMPUBGE
++		p.To.Type = obj.TYPE_BRANCH
++		//p = obj.Appendp(ctxt, p)
++
++		//p.As = ACMPU
++		//p.From.Type = obj.TYPE_REG
++		//p.From.Reg = REG_R3
++		//p.To.Type = obj.TYPE_REG
++		//p.To.Reg = REGSP
++
++		//p = obj.Appendp(ctxt, p)
++		//p.As = ABGE
++		//p.To.Type = obj.TYPE_BRANCH
++
 +	} else if framesize <= obj.StackBig {
 +		// large stack: SP-framesize < stackguard-StackSmall
 +		//	ADD $-framesize, SP, R4
@@ -19158,11 +22983,12 @@ index 0000000..71c6fb5
 +		p.To.Reg = REG_R4
 +
 +		p = obj.Appendp(ctxt, p)
-+		p.As = ACMPU
 +		p.From.Type = obj.TYPE_REG
 +		p.From.Reg = REG_R3
-+		p.To.Type = obj.TYPE_REG
-+		p.To.Reg = REG_R4
++		p.Reg = REG_R4
++		p.As = ACMPUBGE
++		p.To.Type = obj.TYPE_BRANCH
++
 +	} else {
 +		// Such a large stack we need to protect against wraparound.
 +		// If SP is close to zero:
@@ -19177,8 +23003,8 @@ index 0000000..71c6fb5
 +		//	BEQ	label-of-call-to-morestack
 +		//	ADD	$StackGuard, SP, R4
 +		//	SUB	R3, R4
-+		//	MOVD	$(framesize+(StackGuard-StackSmall)), R31
-+		//	CMPU	R31, R4
++		//	MOVD	$(framesize+(StackGuard-StackSmall)), TEMP
++		//	CMPUBGE	TEMP, R4
 +		p = obj.Appendp(ctxt, p)
 +
 +		p.As = ACMP
@@ -19215,30 +23041,28 @@ index 0000000..71c6fb5
 +		p.To.Reg = REGTMP
 +
 +		p = obj.Appendp(ctxt, p)
-+		p.As = ACMPU
 +		p.From.Type = obj.TYPE_REG
 +		p.From.Reg = REGTMP
-+		p.To.Type = obj.TYPE_REG
-+		p.To.Reg = REG_R4
++		p.Reg = REG_R4
++		p.As = ACMPUBGE
++		p.To.Type = obj.TYPE_BRANCH
 +	}
 +
-+	// q1: BLT	done
-+	p = obj.Appendp(ctxt, p)
-+	q1 := p
++	return p, q
++}
 +
-+	p.As = ABLT
-+	p.To.Type = obj.TYPE_BRANCH
++func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog) *obj.Prog {
 +
 +	// MOVD	LR, R5
 +	p = obj.Appendp(ctxt, p)
-+
++	pPre.Pcond = p
 +	p.As = AMOVD
 +	p.From.Type = obj.TYPE_REG
 +	p.From.Reg = REG_LR
 +	p.To.Type = obj.TYPE_REG
 +	p.To.Reg = REG_R5
-+	if q != nil {
-+		q.Pcond = p
++	if pPreempt != nil {
++		pPreempt.Pcond = p
 +	}
 +
 +	// BL	runtime.morestack(SB)
@@ -19260,13 +23084,6 @@ index 0000000..71c6fb5
 +	p.As = ABR
 +	p.To.Type = obj.TYPE_BRANCH
 +	p.Pcond = ctxt.Cursym.Text.Link
-+
-+	// placeholder for q1's jump target
-+	p = obj.Appendp(ctxt, p)
-+
-+	p.As = obj.ANOP // zero-width place holder
-+	q1.Pcond = p
-+
 +	return p
 +}
 +
@@ -19454,6 +23271,9 @@ index 0000000..71c6fb5
 +	ASTCKC: true,
 +	ASTCKE: true,
 +	ASTCKF: true,
++	ANEG:   true,
++	AVONE:  true,
++	AVZERO: true,
 +}
 +
 +var Links390x = obj.LinkArch{
@@ -19469,6 +23289,1069 @@ index 0000000..71c6fb5
 +	Ptrsize:    8,
 +	Regsize:    8,
 +}
+diff --git a/src/cmd/internal/obj/s390x/vector.go b/src/cmd/internal/obj/s390x/vector.go
+new file mode 100644
+index 0000000..36b4783
+--- /dev/null
++++ b/src/cmd/internal/obj/s390x/vector.go
+@@ -0,0 +1,1057 @@
++// Copyright 2016 The Go Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package s390x
++
++// This file contains utility functions for use when
++// assembling vector instructions.
++
++// vop returns the opcode, element size and condition
++// setting for the given (possibly extended) mnemonic.
++func vop(as int16) (opcode, es, cs uint32) {
++	switch as {
++	default:
++		return 0, 0, 0
++	case AVA:
++		return OP_VA, 0, 0
++	case AVAB:
++		return OP_VA, 0, 0
++	case AVAH:
++		return OP_VA, 1, 0
++	case AVAF:
++		return OP_VA, 2, 0
++	case AVAG:
++		return OP_VA, 3, 0
++	case AVAQ:
++		return OP_VA, 4, 0
++	case AVACC:
++		return OP_VACC, 0, 0
++	case AVACCB:
++		return OP_VACC, 0, 0
++	case AVACCH:
++		return OP_VACC, 1, 0
++	case AVACCF:
++		return OP_VACC, 2, 0
++	case AVACCG:
++		return OP_VACC, 3, 0
++	case AVACCQ:
++		return OP_VACC, 4, 0
++	case AVAC:
++		return OP_VAC, 0, 0
++	case AVACQ:
++		return OP_VAC, 4, 0
++	case AVACCC:
++		return OP_VACCC, 0, 0
++	case AVACCCQ:
++		return OP_VACCC, 4, 0
++	case AVN:
++		return OP_VN, 0, 0
++	case AVNC:
++		return OP_VNC, 0, 0
++	case AVAVG:
++		return OP_VAVG, 0, 0
++	case AVAVGB:
++		return OP_VAVG, 0, 0
++	case AVAVGH:
++		return OP_VAVG, 1, 0
++	case AVAVGF:
++		return OP_VAVG, 2, 0
++	case AVAVGG:
++		return OP_VAVG, 3, 0
++	case AVAVGL:
++		return OP_VAVGL, 0, 0
++	case AVAVGLB:
++		return OP_VAVGL, 0, 0
++	case AVAVGLH:
++		return OP_VAVGL, 1, 0
++	case AVAVGLF:
++		return OP_VAVGL, 2, 0
++	case AVAVGLG:
++		return OP_VAVGL, 3, 0
++	case AVCKSM:
++		return OP_VCKSM, 0, 0
++	case AVCEQ:
++		return OP_VCEQ, 0, 0
++	case AVCEQB:
++		return OP_VCEQ, 0, 0
++	case AVCEQH:
++		return OP_VCEQ, 1, 0
++	case AVCEQF:
++		return OP_VCEQ, 2, 0
++	case AVCEQG:
++		return OP_VCEQ, 3, 0
++	case AVCEQBS:
++		return OP_VCEQ, 0, 1
++	case AVCEQHS:
++		return OP_VCEQ, 1, 1
++	case AVCEQFS:
++		return OP_VCEQ, 2, 1
++	case AVCEQGS:
++		return OP_VCEQ, 3, 1
++	case AVCH:
++		return OP_VCH, 0, 0
++	case AVCHB:
++		return OP_VCH, 0, 0
++	case AVCHH:
++		return OP_VCH, 1, 0
++	case AVCHF:
++		return OP_VCH, 2, 0
++	case AVCHG:
++		return OP_VCH, 3, 0
++	case AVCHBS:
++		return OP_VCH, 0, 1
++	case AVCHHS:
++		return OP_VCH, 1, 1
++	case AVCHFS:
++		return OP_VCH, 2, 1
++	case AVCHGS:
++		return OP_VCH, 3, 1
++	case AVCHL:
++		return OP_VCHL, 0, 0
++	case AVCHLB:
++		return OP_VCHL, 0, 0
++	case AVCHLH:
++		return OP_VCHL, 1, 0
++	case AVCHLF:
++		return OP_VCHL, 2, 0
++	case AVCHLG:
++		return OP_VCHL, 3, 0
++	case AVCHLBS:
++		return OP_VCHL, 0, 1
++	case AVCHLHS:
++		return OP_VCHL, 1, 1
++	case AVCHLFS:
++		return OP_VCHL, 2, 1
++	case AVCHLGS:
++		return OP_VCHL, 3, 1
++	case AVCLZ:
++		return OP_VCLZ, 0, 0
++	case AVCLZB:
++		return OP_VCLZ, 0, 0
++	case AVCLZH:
++		return OP_VCLZ, 1, 0
++	case AVCLZF:
++		return OP_VCLZ, 2, 0
++	case AVCLZG:
++		return OP_VCLZ, 3, 0
++	case AVCTZ:
++		return OP_VCTZ, 0, 0
++	case AVCTZB:
++		return OP_VCTZ, 0, 0
++	case AVCTZH:
++		return OP_VCTZ, 1, 0
++	case AVCTZF:
++		return OP_VCTZ, 2, 0
++	case AVCTZG:
++		return OP_VCTZ, 3, 0
++	case AVEC:
++		return OP_VEC, 0, 0
++	case AVECB:
++		return OP_VEC, 0, 0
++	case AVECH:
++		return OP_VEC, 1, 0
++	case AVECF:
++		return OP_VEC, 2, 0
++	case AVECG:
++		return OP_VEC, 3, 0
++	case AVECL:
++		return OP_VECL, 0, 0
++	case AVECLB:
++		return OP_VECL, 0, 0
++	case AVECLH:
++		return OP_VECL, 1, 0
++	case AVECLF:
++		return OP_VECL, 2, 0
++	case AVECLG:
++		return OP_VECL, 3, 0
++	case AVERIM:
++		return OP_VERIM, 0, 0
++	case AVERIMB:
++		return OP_VERIM, 0, 0
++	case AVERIMH:
++		return OP_VERIM, 1, 0
++	case AVERIMF:
++		return OP_VERIM, 2, 0
++	case AVERIMG:
++		return OP_VERIM, 3, 0
++	case AVERLL:
++		return OP_VERLL, 0, 0
++	case AVERLLB:
++		return OP_VERLL, 0, 0
++	case AVERLLH:
++		return OP_VERLL, 1, 0
++	case AVERLLF:
++		return OP_VERLL, 2, 0
++	case AVERLLG:
++		return OP_VERLL, 3, 0
++	case AVERLLV:
++		return OP_VERLLV, 0, 0
++	case AVERLLVB:
++		return OP_VERLLV, 0, 0
++	case AVERLLVH:
++		return OP_VERLLV, 1, 0
++	case AVERLLVF:
++		return OP_VERLLV, 2, 0
++	case AVERLLVG:
++		return OP_VERLLV, 3, 0
++	case AVESLV:
++		return OP_VESLV, 0, 0
++	case AVESLVB:
++		return OP_VESLV, 0, 0
++	case AVESLVH:
++		return OP_VESLV, 1, 0
++	case AVESLVF:
++		return OP_VESLV, 2, 0
++	case AVESLVG:
++		return OP_VESLV, 3, 0
++	case AVESL:
++		return OP_VESL, 0, 0
++	case AVESLB:
++		return OP_VESL, 0, 0
++	case AVESLH:
++		return OP_VESL, 1, 0
++	case AVESLF:
++		return OP_VESL, 2, 0
++	case AVESLG:
++		return OP_VESL, 3, 0
++	case AVESRA:
++		return OP_VESRA, 0, 0
++	case AVESRAB:
++		return OP_VESRA, 0, 0
++	case AVESRAH:
++		return OP_VESRA, 1, 0
++	case AVESRAF:
++		return OP_VESRA, 2, 0
++	case AVESRAG:
++		return OP_VESRA, 3, 0
++	case AVESRAV:
++		return OP_VESRAV, 0, 0
++	case AVESRAVB:
++		return OP_VESRAV, 0, 0
++	case AVESRAVH:
++		return OP_VESRAV, 1, 0
++	case AVESRAVF:
++		return OP_VESRAV, 2, 0
++	case AVESRAVG:
++		return OP_VESRAV, 3, 0
++	case AVESRL:
++		return OP_VESRL, 0, 0
++	case AVESRLB:
++		return OP_VESRL, 0, 0
++	case AVESRLH:
++		return OP_VESRL, 1, 0
++	case AVESRLF:
++		return OP_VESRL, 2, 0
++	case AVESRLG:
++		return OP_VESRL, 3, 0
++	case AVESRLV:
++		return OP_VESRLV, 0, 0
++	case AVESRLVB:
++		return OP_VESRLV, 0, 0
++	case AVESRLVH:
++		return OP_VESRLV, 1, 0
++	case AVESRLVF:
++		return OP_VESRLV, 2, 0
++	case AVESRLVG:
++		return OP_VESRLV, 3, 0
++	case AVX:
++		return OP_VX, 0, 0
++	case AVFAE:
++		return OP_VFAE, 0, 0
++	case AVFAEB:
++		return OP_VFAE, 0, 0
++	case AVFAEH:
++		return OP_VFAE, 1, 0
++	case AVFAEF:
++		return OP_VFAE, 2, 0
++	case AVFAEBS:
++		return OP_VFAE, 0, 1
++	case AVFAEHS:
++		return OP_VFAE, 1, 1
++	case AVFAEFS:
++		return OP_VFAE, 2, 1
++	case AVFAEZB:
++		return OP_VFAE, 0, 2
++	case AVFAEZH:
++		return OP_VFAE, 1, 2
++	case AVFAEZF:
++		return OP_VFAE, 2, 2
++	case AVFAEZBS:
++		return OP_VFAE, 0, 3
++	case AVFAEZHS:
++		return OP_VFAE, 1, 3
++	case AVFAEZFS:
++		return OP_VFAE, 2, 3
++	case AVFEE:
++		return OP_VFEE, 0, 0
++	case AVFEEB:
++		return OP_VFEE, 0, 0
++	case AVFEEH:
++		return OP_VFEE, 1, 0
++	case AVFEEF:
++		return OP_VFEE, 2, 0
++	case AVFEEBS:
++		return OP_VFEE, 0, 1
++	case AVFEEHS:
++		return OP_VFEE, 1, 1
++	case AVFEEFS:
++		return OP_VFEE, 2, 1
++	case AVFEEZB:
++		return OP_VFEE, 0, 2
++	case AVFEEZH:
++		return OP_VFEE, 1, 2
++	case AVFEEZF:
++		return OP_VFEE, 2, 2
++	case AVFEEZBS:
++		return OP_VFEE, 0, 3
++	case AVFEEZHS:
++		return OP_VFEE, 1, 3
++	case AVFEEZFS:
++		return OP_VFEE, 2, 3
++	case AVFENE:
++		return OP_VFENE, 0, 0
++	case AVFENEB:
++		return OP_VFENE, 0, 0
++	case AVFENEH:
++		return OP_VFENE, 1, 0
++	case AVFENEF:
++		return OP_VFENE, 2, 0
++	case AVFENEBS:
++		return OP_VFENE, 0, 1
++	case AVFENEHS:
++		return OP_VFENE, 1, 1
++	case AVFENEFS:
++		return OP_VFENE, 2, 1
++	case AVFENEZB:
++		return OP_VFENE, 0, 2
++	case AVFENEZH:
++		return OP_VFENE, 1, 2
++	case AVFENEZF:
++		return OP_VFENE, 2, 2
++	case AVFENEZBS:
++		return OP_VFENE, 0, 3
++	case AVFENEZHS:
++		return OP_VFENE, 1, 3
++	case AVFENEZFS:
++		return OP_VFENE, 2, 3
++	case AVFA:
++		return OP_VFA, 0, 0
++	case AVFADB:
++		return OP_VFA, 3, 0
++	case AWFADB:
++		return OP_VFA, 3, 0
++	case AWFK:
++		return OP_WFK, 0, 0
++	case AWFKDB:
++		return OP_WFK, 3, 0
++	case AVFCE:
++		return OP_VFCE, 0, 0
++	case AVFCEDB:
++		return OP_VFCE, 3, 0
++	case AVFCEDBS:
++		return OP_VFCE, 3, 1
++	case AWFCEDB:
++		return OP_VFCE, 3, 0
++	case AWFCEDBS:
++		return OP_VFCE, 3, 1
++	case AVFCH:
++		return OP_VFCH, 0, 0
++	case AVFCHDB:
++		return OP_VFCH, 3, 0
++	case AVFCHDBS:
++		return OP_VFCH, 3, 1
++	case AWFCHDB:
++		return OP_VFCH, 3, 0
++	case AWFCHDBS:
++		return OP_VFCH, 3, 1
++	case AVFCHE:
++		return OP_VFCHE, 0, 0
++	case AVFCHEDB:
++		return OP_VFCHE, 3, 0
++	case AVFCHEDBS:
++		return OP_VFCHE, 3, 1
++	case AWFCHEDB:
++		return OP_VFCHE, 3, 0
++	case AWFCHEDBS:
++		return OP_VFCHE, 3, 1
++	case AWFC:
++		return OP_WFC, 0, 0
++	case AWFCDB:
++		return OP_WFC, 3, 0
++	case AVCDG:
++		return OP_VCDG, 0, 0
++	case AVCDGB:
++		return OP_VCDG, 3, 0
++	case AWCDGB:
++		return OP_VCDG, 3, 0
++	case AVCDLG:
++		return OP_VCDLG, 0, 0
++	case AVCDLGB:
++		return OP_VCDLG, 3, 0
++	case AWCDLGB:
++		return OP_VCDLG, 3, 0
++	case AVCGD:
++		return OP_VCGD, 0, 0
++	case AVCGDB:
++		return OP_VCGD, 3, 0
++	case AWCGDB:
++		return OP_VCGD, 3, 0
++	case AVCLGD:
++		return OP_VCLGD, 0, 0
++	case AVCLGDB:
++		return OP_VCLGD, 3, 0
++	case AWCLGDB:
++		return OP_VCLGD, 3, 0
++	case AVFD:
++		return OP_VFD, 0, 0
++	case AVFDDB:
++		return OP_VFD, 3, 0
++	case AWFDDB:
++		return OP_VFD, 3, 0
++	case AVLDE:
++		return OP_VLDE, 0, 0
++	case AVLDEB:
++		return OP_VLDE, 2, 0
++	case AWLDEB:
++		return OP_VLDE, 2, 0
++	case AVLED:
++		return OP_VLED, 0, 0
++	case AVLEDB:
++		return OP_VLED, 3, 0
++	case AWLEDB:
++		return OP_VLED, 3, 0
++	case AVFM:
++		return OP_VFM, 0, 0
++	case AVFMDB:
++		return OP_VFM, 3, 0
++	case AWFMDB:
++		return OP_VFM, 3, 0
++	case AVFMA:
++		return OP_VFMA, 0, 0
++	case AVFMADB:
++		return OP_VFMA, 3, 0
++	case AWFMADB:
++		return OP_VFMA, 3, 0
++	case AVFMS:
++		return OP_VFMS, 0, 0
++	case AVFMSDB:
++		return OP_VFMS, 3, 0
++	case AWFMSDB:
++		return OP_VFMS, 3, 0
++	case AVFPSO:
++		return OP_VFPSO, 0, 0
++	case AVFPSODB:
++		return OP_VFPSO, 3, 0
++	case AWFPSODB:
++		return OP_VFPSO, 3, 0
++	case AVFLCDB:
++		return OP_VFPSO, 3, 0
++	case AWFLCDB:
++		return OP_VFPSO, 3, 0
++	case AVFLNDB:
++		return OP_VFPSO, 3, 1
++	case AWFLNDB:
++		return OP_VFPSO, 3, 1
++	case AVFLPDB:
++		return OP_VFPSO, 3, 2
++	case AWFLPDB:
++		return OP_VFPSO, 3, 2
++	case AVFSQ:
++		return OP_VFSQ, 0, 0
++	case AVFSQDB:
++		return OP_VFSQ, 3, 0
++	case AWFSQDB:
++		return OP_VFSQ, 3, 0
++	case AVFS:
++		return OP_VFS, 0, 0
++	case AVFSDB:
++		return OP_VFS, 3, 0
++	case AWFSDB:
++		return OP_VFS, 3, 0
++	case AVFTCI:
++		return OP_VFTCI, 0, 0
++	case AVFTCIDB:
++		return OP_VFTCI, 3, 0
++	case AWFTCIDB:
++		return OP_VFTCI, 3, 0
++	case AVGFM:
++		return OP_VGFM, 0, 0
++	case AVGFMB:
++		return OP_VGFM, 0, 0
++	case AVGFMH:
++		return OP_VGFM, 1, 0
++	case AVGFMF:
++		return OP_VGFM, 2, 0
++	case AVGFMG:
++		return OP_VGFM, 3, 0
++	case AVGFMA:
++		return OP_VGFMA, 0, 0
++	case AVGFMAB:
++		return OP_VGFMA, 0, 0
++	case AVGFMAH:
++		return OP_VGFMA, 1, 0
++	case AVGFMAF:
++		return OP_VGFMA, 2, 0
++	case AVGFMAG:
++		return OP_VGFMA, 3, 0
++	case AVGEF:
++		return OP_VGEF, 0, 0
++	case AVGEG:
++		return OP_VGEG, 0, 0
++	case AVGBM:
++		return OP_VGBM, 0, 0
++	case AVZERO:
++		return OP_VGBM, 0, 0
++	case AVONE:
++		return OP_VGBM, 0, 0
++	case AVGM:
++		return OP_VGM, 0, 0
++	case AVGMB:
++		return OP_VGM, 0, 0
++	case AVGMH:
++		return OP_VGM, 1, 0
++	case AVGMF:
++		return OP_VGM, 2, 0
++	case AVGMG:
++		return OP_VGM, 3, 0
++	case AVISTR:
++		return OP_VISTR, 0, 0
++	case AVISTRB:
++		return OP_VISTR, 0, 0
++	case AVISTRH:
++		return OP_VISTR, 1, 0
++	case AVISTRF:
++		return OP_VISTR, 2, 0
++	case AVISTRBS:
++		return OP_VISTR, 0, 1
++	case AVISTRHS:
++		return OP_VISTR, 1, 1
++	case AVISTRFS:
++		return OP_VISTR, 2, 1
++	case AVL:
++		return OP_VL, 0, 0
++	case AVLR:
++		return OP_VLR, 0, 0
++	case AVLREP:
++		return OP_VLREP, 0, 0
++	case AVLREPB:
++		return OP_VLREP, 0, 0
++	case AVLREPH:
++		return OP_VLREP, 1, 0
++	case AVLREPF:
++		return OP_VLREP, 2, 0
++	case AVLREPG:
++		return OP_VLREP, 3, 0
++	case AVLC:
++		return OP_VLC, 0, 0
++	case AVLCB:
++		return OP_VLC, 0, 0
++	case AVLCH:
++		return OP_VLC, 1, 0
++	case AVLCF:
++		return OP_VLC, 2, 0
++	case AVLCG:
++		return OP_VLC, 3, 0
++	case AVLEH:
++		return OP_VLEH, 0, 0
++	case AVLEF:
++		return OP_VLEF, 0, 0
++	case AVLEG:
++		return OP_VLEG, 0, 0
++	case AVLEB:
++		return OP_VLEB, 0, 0
++	case AVLEIH:
++		return OP_VLEIH, 0, 0
++	case AVLEIF:
++		return OP_VLEIF, 0, 0
++	case AVLEIG:
++		return OP_VLEIG, 0, 0
++	case AVLEIB:
++		return OP_VLEIB, 0, 0
++	case AVFI:
++		return OP_VFI, 0, 0
++	case AVFIDB:
++		return OP_VFI, 3, 0
++	case AWFIDB:
++		return OP_VFI, 3, 0
++	case AVLGV:
++		return OP_VLGV, 0, 0
++	case AVLGVB:
++		return OP_VLGV, 0, 0
++	case AVLGVH:
++		return OP_VLGV, 1, 0
++	case AVLGVF:
++		return OP_VLGV, 2, 0
++	case AVLGVG:
++		return OP_VLGV, 3, 0
++	case AVLLEZ:
++		return OP_VLLEZ, 0, 0
++	case AVLLEZB:
++		return OP_VLLEZ, 0, 0
++	case AVLLEZH:
++		return OP_VLLEZ, 1, 0
++	case AVLLEZF:
++		return OP_VLLEZ, 2, 0
++	case AVLLEZG:
++		return OP_VLLEZ, 3, 0
++	case AVLM:
++		return OP_VLM, 0, 0
++	case AVLP:
++		return OP_VLP, 0, 0
++	case AVLPB:
++		return OP_VLP, 0, 0
++	case AVLPH:
++		return OP_VLP, 1, 0
++	case AVLPF:
++		return OP_VLP, 2, 0
++	case AVLPG:
++		return OP_VLP, 3, 0
++	case AVLBB:
++		return OP_VLBB, 0, 0
++	case AVLVG:
++		return OP_VLVG, 0, 0
++	case AVLVGB:
++		return OP_VLVG, 0, 0
++	case AVLVGH:
++		return OP_VLVG, 1, 0
++	case AVLVGF:
++		return OP_VLVG, 2, 0
++	case AVLVGG:
++		return OP_VLVG, 3, 0
++	case AVLVGP:
++		return OP_VLVGP, 0, 0
++	case AVLL:
++		return OP_VLL, 0, 0
++	case AVMX:
++		return OP_VMX, 0, 0
++	case AVMXB:
++		return OP_VMX, 0, 0
++	case AVMXH:
++		return OP_VMX, 1, 0
++	case AVMXF:
++		return OP_VMX, 2, 0
++	case AVMXG:
++		return OP_VMX, 3, 0
++	case AVMXL:
++		return OP_VMXL, 0, 0
++	case AVMXLB:
++		return OP_VMXL, 0, 0
++	case AVMXLH:
++		return OP_VMXL, 1, 0
++	case AVMXLF:
++		return OP_VMXL, 2, 0
++	case AVMXLG:
++		return OP_VMXL, 3, 0
++	case AVMRH:
++		return OP_VMRH, 0, 0
++	case AVMRHB:
++		return OP_VMRH, 0, 0
++	case AVMRHH:
++		return OP_VMRH, 1, 0
++	case AVMRHF:
++		return OP_VMRH, 2, 0
++	case AVMRHG:
++		return OP_VMRH, 3, 0
++	case AVMRL:
++		return OP_VMRL, 0, 0
++	case AVMRLB:
++		return OP_VMRL, 0, 0
++	case AVMRLH:
++		return OP_VMRL, 1, 0
++	case AVMRLF:
++		return OP_VMRL, 2, 0
++	case AVMRLG:
++		return OP_VMRL, 3, 0
++	case AVMN:
++		return OP_VMN, 0, 0
++	case AVMNB:
++		return OP_VMN, 0, 0
++	case AVMNH:
++		return OP_VMN, 1, 0
++	case AVMNF:
++		return OP_VMN, 2, 0
++	case AVMNG:
++		return OP_VMN, 3, 0
++	case AVMNL:
++		return OP_VMNL, 0, 0
++	case AVMNLB:
++		return OP_VMNL, 0, 0
++	case AVMNLH:
++		return OP_VMNL, 1, 0
++	case AVMNLF:
++		return OP_VMNL, 2, 0
++	case AVMNLG:
++		return OP_VMNL, 3, 0
++	case AVMAE:
++		return OP_VMAE, 0, 0
++	case AVMAEB:
++		return OP_VMAE, 0, 0
++	case AVMAEH:
++		return OP_VMAE, 1, 0
++	case AVMAEF:
++		return OP_VMAE, 2, 0
++	case AVMAH:
++		return OP_VMAH, 0, 0
++	case AVMAHB:
++		return OP_VMAH, 0, 0
++	case AVMAHH:
++		return OP_VMAH, 1, 0
++	case AVMAHF:
++		return OP_VMAH, 2, 0
++	case AVMALE:
++		return OP_VMALE, 0, 0
++	case AVMALEB:
++		return OP_VMALE, 0, 0
++	case AVMALEH:
++		return OP_VMALE, 1, 0
++	case AVMALEF:
++		return OP_VMALE, 2, 0
++	case AVMALH:
++		return OP_VMALH, 0, 0
++	case AVMALHB:
++		return OP_VMALH, 0, 0
++	case AVMALHH:
++		return OP_VMALH, 1, 0
++	case AVMALHF:
++		return OP_VMALH, 2, 0
++	case AVMALO:
++		return OP_VMALO, 0, 0
++	case AVMALOB:
++		return OP_VMALO, 0, 0
++	case AVMALOH:
++		return OP_VMALO, 1, 0
++	case AVMALOF:
++		return OP_VMALO, 2, 0
++	case AVMAL:
++		return OP_VMAL, 0, 0
++	case AVMALB:
++		return OP_VMAL, 0, 0
++	case AVMALHW:
++		return OP_VMAL, 1, 0
++	case AVMALF:
++		return OP_VMAL, 2, 0
++	case AVMAO:
++		return OP_VMAO, 0, 0
++	case AVMAOB:
++		return OP_VMAO, 0, 0
++	case AVMAOH:
++		return OP_VMAO, 1, 0
++	case AVMAOF:
++		return OP_VMAO, 2, 0
++	case AVME:
++		return OP_VME, 0, 0
++	case AVMEB:
++		return OP_VME, 0, 0
++	case AVMEH:
++		return OP_VME, 1, 0
++	case AVMEF:
++		return OP_VME, 2, 0
++	case AVMH:
++		return OP_VMH, 0, 0
++	case AVMHB:
++		return OP_VMH, 0, 0
++	case AVMHH:
++		return OP_VMH, 1, 0
++	case AVMHF:
++		return OP_VMH, 2, 0
++	case AVMLE:
++		return OP_VMLE, 0, 0
++	case AVMLEB:
++		return OP_VMLE, 0, 0
++	case AVMLEH:
++		return OP_VMLE, 1, 0
++	case AVMLEF:
++		return OP_VMLE, 2, 0
++	case AVMLH:
++		return OP_VMLH, 0, 0
++	case AVMLHB:
++		return OP_VMLH, 0, 0
++	case AVMLHH:
++		return OP_VMLH, 1, 0
++	case AVMLHF:
++		return OP_VMLH, 2, 0
++	case AVMLO:
++		return OP_VMLO, 0, 0
++	case AVMLOB:
++		return OP_VMLO, 0, 0
++	case AVMLOH:
++		return OP_VMLO, 1, 0
++	case AVMLOF:
++		return OP_VMLO, 2, 0
++	case AVML:
++		return OP_VML, 0, 0
++	case AVMLB:
++		return OP_VML, 0, 0
++	case AVMLHW:
++		return OP_VML, 1, 0
++	case AVMLF:
++		return OP_VML, 2, 0
++	case AVMO:
++		return OP_VMO, 0, 0
++	case AVMOB:
++		return OP_VMO, 0, 0
++	case AVMOH:
++		return OP_VMO, 1, 0
++	case AVMOF:
++		return OP_VMO, 2, 0
++	case AVNO:
++		return OP_VNO, 0, 0
++	case AVNOT:
++		return OP_VNO, 0, 0
++	case AVO:
++		return OP_VO, 0, 0
++	case AVPK:
++		return OP_VPK, 0, 0
++	case AVPKH:
++		return OP_VPK, 1, 0
++	case AVPKF:
++		return OP_VPK, 2, 0
++	case AVPKG:
++		return OP_VPK, 3, 0
++	case AVPKLS:
++		return OP_VPKLS, 0, 0
++	case AVPKLSH:
++		return OP_VPKLS, 1, 0
++	case AVPKLSF:
++		return OP_VPKLS, 2, 0
++	case AVPKLSG:
++		return OP_VPKLS, 3, 0
++	case AVPKLSHS:
++		return OP_VPKLS, 1, 1
++	case AVPKLSFS:
++		return OP_VPKLS, 2, 1
++	case AVPKLSGS:
++		return OP_VPKLS, 3, 1
++	case AVPKS:
++		return OP_VPKS, 0, 0
++	case AVPKSH:
++		return OP_VPKS, 1, 0
++	case AVPKSF:
++		return OP_VPKS, 2, 0
++	case AVPKSG:
++		return OP_VPKS, 3, 0
++	case AVPKSHS:
++		return OP_VPKS, 1, 1
++	case AVPKSFS:
++		return OP_VPKS, 2, 1
++	case AVPKSGS:
++		return OP_VPKS, 3, 1
++	case AVPERM:
++		return OP_VPERM, 0, 0
++	case AVPDI:
++		return OP_VPDI, 0, 0
++	case AVPOPCT:
++		return OP_VPOPCT, 0, 0
++	case AVREP:
++		return OP_VREP, 0, 0
++	case AVREPB:
++		return OP_VREP, 0, 0
++	case AVREPH:
++		return OP_VREP, 1, 0
++	case AVREPF:
++		return OP_VREP, 2, 0
++	case AVREPG:
++		return OP_VREP, 3, 0
++	case AVREPI:
++		return OP_VREPI, 0, 0
++	case AVREPIB:
++		return OP_VREPI, 0, 0
++	case AVREPIH:
++		return OP_VREPI, 1, 0
++	case AVREPIF:
++		return OP_VREPI, 2, 0
++	case AVREPIG:
++		return OP_VREPI, 3, 0
++	case AVSCEF:
++		return OP_VSCEF, 0, 0
++	case AVSCEG:
++		return OP_VSCEG, 0, 0
++	case AVSEL:
++		return OP_VSEL, 0, 0
++	case AVSL:
++		return OP_VSL, 0, 0
++	case AVSLB:
++		return OP_VSLB, 0, 0
++	case AVSLDB:
++		return OP_VSLDB, 0, 0
++	case AVSRA:
++		return OP_VSRA, 0, 0
++	case AVSRAB:
++		return OP_VSRAB, 0, 0
++	case AVSRL:
++		return OP_VSRL, 0, 0
++	case AVSRLB:
++		return OP_VSRLB, 0, 0
++	case AVSEG:
++		return OP_VSEG, 0, 0
++	case AVSEGB:
++		return OP_VSEG, 0, 0
++	case AVSEGH:
++		return OP_VSEG, 1, 0
++	case AVSEGF:
++		return OP_VSEG, 2, 0
++	case AVST:
++		return OP_VST, 0, 0
++	case AVSTEH:
++		return OP_VSTEH, 0, 0
++	case AVSTEF:
++		return OP_VSTEF, 0, 0
++	case AVSTEG:
++		return OP_VSTEG, 0, 0
++	case AVSTEB:
++		return OP_VSTEB, 0, 0
++	case AVSTM:
++		return OP_VSTM, 0, 0
++	case AVSTL:
++		return OP_VSTL, 0, 0
++	case AVSTRC:
++		return OP_VSTRC, 0, 0
++	case AVSTRCB:
++		return OP_VSTRC, 0, 0
++	case AVSTRCH:
++		return OP_VSTRC, 1, 0
++	case AVSTRCF:
++		return OP_VSTRC, 2, 0
++	case AVSTRCBS:
++		return OP_VSTRC, 0, 1
++	case AVSTRCHS:
++		return OP_VSTRC, 1, 1
++	case AVSTRCFS:
++		return OP_VSTRC, 2, 1
++	case AVSTRCZB:
++		return OP_VSTRC, 0, 2
++	case AVSTRCZH:
++		return OP_VSTRC, 1, 2
++	case AVSTRCZF:
++		return OP_VSTRC, 2, 2
++	case AVSTRCZBS:
++		return OP_VSTRC, 0, 3
++	case AVSTRCZHS:
++		return OP_VSTRC, 1, 3
++	case AVSTRCZFS:
++		return OP_VSTRC, 2, 3
++	case AVS:
++		return OP_VS, 0, 0
++	case AVSB:
++		return OP_VS, 0, 0
++	case AVSH:
++		return OP_VS, 1, 0
++	case AVSF:
++		return OP_VS, 2, 0
++	case AVSG:
++		return OP_VS, 3, 0
++	case AVSQ:
++		return OP_VS, 4, 0
++	case AVSCBI:
++		return OP_VSCBI, 0, 0
++	case AVSCBIB:
++		return OP_VSCBI, 0, 0
++	case AVSCBIH:
++		return OP_VSCBI, 1, 0
++	case AVSCBIF:
++		return OP_VSCBI, 2, 0
++	case AVSCBIG:
++		return OP_VSCBI, 3, 0
++	case AVSCBIQ:
++		return OP_VSCBI, 4, 0
++	case AVSBCBI:
++		return OP_VSBCBI, 0, 0
++	case AVSBCBIQ:
++		return OP_VSBCBI, 4, 0
++	case AVSBI:
++		return OP_VSBI, 0, 0
++	case AVSBIQ:
++		return OP_VSBI, 4, 0
++	case AVSUMG:
++		return OP_VSUMG, 0, 0
++	case AVSUMGH:
++		return OP_VSUMG, 1, 0
++	case AVSUMGF:
++		return OP_VSUMG, 2, 0
++	case AVSUMQ:
++		return OP_VSUMQ, 0, 0
++	case AVSUMQF:
++		return OP_VSUMQ, 1, 0
++	case AVSUMQG:
++		return OP_VSUMQ, 2, 0
++	case AVSUM:
++		return OP_VSUM, 0, 0
++	case AVSUMB:
++		return OP_VSUM, 0, 0
++	case AVSUMH:
++		return OP_VSUM, 1, 0
++	case AVTM:
++		return OP_VTM, 0, 0
++	case AVUPH:
++		return OP_VUPH, 0, 0
++	case AVUPHB:
++		return OP_VUPH, 0, 0
++	case AVUPHH:
++		return OP_VUPH, 1, 0
++	case AVUPHF:
++		return OP_VUPH, 2, 0
++	case AVUPLH:
++		return OP_VUPLH, 0, 0
++	case AVUPLHB:
++		return OP_VUPLH, 0, 0
++	case AVUPLHH:
++		return OP_VUPLH, 1, 0
++	case AVUPLHF:
++		return OP_VUPLH, 2, 0
++	case AVUPLL:
++		return OP_VUPLL, 0, 0
++	case AVUPLLB:
++		return OP_VUPLL, 0, 0
++	case AVUPLLH:
++		return OP_VUPLL, 1, 0
++	case AVUPLLF:
++		return OP_VUPLL, 2, 0
++	case AVUPL:
++		return OP_VUPL, 0, 0
++	case AVUPLB:
++		return OP_VUPL, 0, 0
++	case AVUPLHW:
++		return OP_VUPL, 1, 0
++	case AVUPLF:
++		return OP_VUPL, 2, 0
++	}
++}
++
++// singleElementMask returns the single element mask bits required for the
++// given instruction.
++func singleElementMask(as int16) uint32 {
++	switch as {
++	case AWFADB,
++		AWFK,
++		AWFKDB,
++		AWFCEDB,
++		AWFCEDBS,
++		AWFCHDB,
++		AWFCHDBS,
++		AWFCHEDB,
++		AWFCHEDBS,
++		AWFC,
++		AWFCDB,
++		AWCDGB,
++		AWCDLGB,
++		AWCGDB,
++		AWCLGDB,
++		AWFDDB,
++		AWLDEB,
++		AWLEDB,
++		AWFMDB,
++		AWFMADB,
++		AWFMSDB,
++		AWFPSODB,
++		AWFLCDB,
++		AWFLNDB,
++		AWFLPDB,
++		AWFSQDB,
++		AWFSDB,
++		AWFTCIDB,
++		AWFIDB:
++		return 8
++	}
++	return 0
++}
 diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go
 index 5103299..06391cb 100644
 --- a/src/cmd/internal/obj/util.go
@@ -19489,8 +24372,282 @@ index 5103299..06391cb 100644
  	AMask = 1<<12 - 1 // AND with this to use the opcode as an array index.
  )
  
+diff --git a/src/cmd/internal/obj/x86/a.out.go b/src/cmd/internal/obj/x86/a.out.go
+index 12eaa90..dacf612 100644
+--- a/src/cmd/internal/obj/x86/a.out.go
++++ b/src/cmd/internal/obj/x86/a.out.go
+@@ -289,8 +289,6 @@ const (
+ 	AFMOVX
+ 	AFMOVXP
+ 
+-	AFCOMB
+-	AFCOMBP
+ 	AFCOMD
+ 	AFCOMDP
+ 	AFCOMDPP
+@@ -620,14 +618,7 @@ const (
+ 	APADDUSW
+ 	APADDW
+ 	APAND
+-	APANDB
+-	APANDL
+ 	APANDN
+-	APANDSB
+-	APANDSW
+-	APANDUSB
+-	APANDUSW
+-	APANDW
+ 	APAVGB
+ 	APAVGW
+ 	APCMPEQB
+@@ -644,23 +635,6 @@ const (
+ 	APEXTRD
+ 	APEXTRQ
+ 	APEXTRW
+-	APFACC
+-	APFADD
+-	APFCMPEQ
+-	APFCMPGE
+-	APFCMPGT
+-	APFMAX
+-	APFMIN
+-	APFMUL
+-	APFNACC
+-	APFPNACC
+-	APFRCP
+-	APFRCPI2T
+-	APFRCPIT1
+-	APFRSQIT1
+-	APFRSQRT
+-	APFSUB
+-	APFSUBR
+ 	APHADDD
+ 	APHADDSW
+ 	APHADDW
+@@ -691,7 +665,6 @@ const (
+ 	APMOVZXWD
+ 	APMOVZXWQ
+ 	APMULDQ
+-	APMULHRW
+ 	APMULHUW
+ 	APMULHW
+ 	APMULLD
+@@ -722,7 +695,6 @@ const (
+ 	APSUBUSB
+ 	APSUBUSW
+ 	APSUBW
+-	APSWAPL
+ 	APUNPCKHBW
+ 	APUNPCKHLQ
+ 	APUNPCKHQDQ
+@@ -761,11 +733,6 @@ const (
+ 	AUNPCKLPS
+ 	AXORPD
+ 	AXORPS
+-
+-	APF2IW
+-	APF2IL
+-	API2FW
+-	API2FL
+ 	ARETFW
+ 	ARETFL
+ 	ARETFQ
+diff --git a/src/cmd/internal/obj/x86/anames.go b/src/cmd/internal/obj/x86/anames.go
+index 1875eae..3b59e2f 100644
+--- a/src/cmd/internal/obj/x86/anames.go
++++ b/src/cmd/internal/obj/x86/anames.go
+@@ -255,8 +255,6 @@ var Anames = []string{
+ 	"FMOVWP",
+ 	"FMOVX",
+ 	"FMOVXP",
+-	"FCOMB",
+-	"FCOMBP",
+ 	"FCOMD",
+ 	"FCOMDP",
+ 	"FCOMDPP",
+@@ -569,14 +567,7 @@ var Anames = []string{
+ 	"PADDUSW",
+ 	"PADDW",
+ 	"PAND",
+-	"PANDB",
+-	"PANDL",
+ 	"PANDN",
+-	"PANDSB",
+-	"PANDSW",
+-	"PANDUSB",
+-	"PANDUSW",
+-	"PANDW",
+ 	"PAVGB",
+ 	"PAVGW",
+ 	"PCMPEQB",
+@@ -593,23 +584,6 @@ var Anames = []string{
+ 	"PEXTRD",
+ 	"PEXTRQ",
+ 	"PEXTRW",
+-	"PFACC",
+-	"PFADD",
+-	"PFCMPEQ",
+-	"PFCMPGE",
+-	"PFCMPGT",
+-	"PFMAX",
+-	"PFMIN",
+-	"PFMUL",
+-	"PFNACC",
+-	"PFPNACC",
+-	"PFRCP",
+-	"PFRCPI2T",
+-	"PFRCPIT1",
+-	"PFRSQIT1",
+-	"PFRSQRT",
+-	"PFSUB",
+-	"PFSUBR",
+ 	"PHADDD",
+ 	"PHADDSW",
+ 	"PHADDW",
+@@ -640,7 +614,6 @@ var Anames = []string{
+ 	"PMOVZXWD",
+ 	"PMOVZXWQ",
+ 	"PMULDQ",
+-	"PMULHRW",
+ 	"PMULHUW",
+ 	"PMULHW",
+ 	"PMULLD",
+@@ -671,7 +644,6 @@ var Anames = []string{
+ 	"PSUBUSB",
+ 	"PSUBUSW",
+ 	"PSUBW",
+-	"PSWAPL",
+ 	"PUNPCKHBW",
+ 	"PUNPCKHLQ",
+ 	"PUNPCKHQDQ",
+@@ -710,10 +682,6 @@ var Anames = []string{
+ 	"UNPCKLPS",
+ 	"XORPD",
+ 	"XORPS",
+-	"PF2IW",
+-	"PF2IL",
+-	"PI2FW",
+-	"PI2FL",
+ 	"RETFW",
+ 	"RETFL",
+ 	"RETFQ",
+diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
+index 4ed1d87..1153506 100644
+--- a/src/cmd/internal/obj/x86/asm6.go
++++ b/src/cmd/internal/obj/x86/asm6.go
+@@ -184,7 +184,6 @@ const (
+ 	Zm2_r
+ 	Zm_r_xm
+ 	Zm_r_i_xm
+-	Zm_r_3d
+ 	Zm_r_xm_nr
+ 	Zr_m_xm_nr
+ 	Zibm_r /* mmx1,mmx2/mem64,imm8 */
+@@ -753,10 +752,6 @@ var yxrrl = []ytab{
+ 	{Yxr, Ynone, Yrl, Zm_r, 1},
+ }
+ 
+-var ymfp = []ytab{
+-	{Ymm, Ynone, Ymr, Zm_r_3d, 1},
+-}
+-
+ var ymrxr = []ytab{
+ 	{Ymr, Ynone, Yxr, Zm_r, 1},
+ 	{Yxm, Ynone, Yxr, Zm_r_xm, 1},
+@@ -1085,7 +1080,6 @@ var optab =
+ 	{ACVTPD2PS, yxm, Pe, [23]uint8{0x5a}},
+ 	{ACVTPS2PL, yxcvm1, Px, [23]uint8{Pe, 0x5b, Pm, 0x2d}},
+ 	{ACVTPS2PD, yxm, Pm, [23]uint8{0x5a}},
+-	{API2FW, ymfp, Px, [23]uint8{0x0c}},
+ 	{ACVTSD2SL, yxcvfl, Pf2, [23]uint8{0x2d}},
+ 	{ACVTSD2SQ, yxcvfq, Pw, [23]uint8{Pf2, 0x2d}},
+ 	{ACVTSD2SS, yxm, Pf2, [23]uint8{0x5a}},
+@@ -1303,26 +1297,6 @@ var optab =
+ 	{APEXTRB, yextr, Pq, [23]uint8{0x3a, 0x14, 00}},
+ 	{APEXTRD, yextr, Pq, [23]uint8{0x3a, 0x16, 00}},
+ 	{APEXTRQ, yextr, Pq3, [23]uint8{0x3a, 0x16, 00}},
+-	{APF2IL, ymfp, Px, [23]uint8{0x1d}},
+-	{APF2IW, ymfp, Px, [23]uint8{0x1c}},
+-	{API2FL, ymfp, Px, [23]uint8{0x0d}},
+-	{APFACC, ymfp, Px, [23]uint8{0xae}},
+-	{APFADD, ymfp, Px, [23]uint8{0x9e}},
+-	{APFCMPEQ, ymfp, Px, [23]uint8{0xb0}},
+-	{APFCMPGE, ymfp, Px, [23]uint8{0x90}},
+-	{APFCMPGT, ymfp, Px, [23]uint8{0xa0}},
+-	{APFMAX, ymfp, Px, [23]uint8{0xa4}},
+-	{APFMIN, ymfp, Px, [23]uint8{0x94}},
+-	{APFMUL, ymfp, Px, [23]uint8{0xb4}},
+-	{APFNACC, ymfp, Px, [23]uint8{0x8a}},
+-	{APFPNACC, ymfp, Px, [23]uint8{0x8e}},
+-	{APFRCP, ymfp, Px, [23]uint8{0x96}},
+-	{APFRCPIT1, ymfp, Px, [23]uint8{0xa6}},
+-	{APFRCPI2T, ymfp, Px, [23]uint8{0xb6}},
+-	{APFRSQIT1, ymfp, Px, [23]uint8{0xa7}},
+-	{APFRSQRT, ymfp, Px, [23]uint8{0x97}},
+-	{APFSUB, ymfp, Px, [23]uint8{0x9a}},
+-	{APFSUBR, ymfp, Px, [23]uint8{0xaa}},
+ 	{APHADDD, ymmxmm0f38, Px, [23]uint8{0x0F, 0x38, 0x02, 0, 0x66, 0x0F, 0x38, 0x02, 0}},
+ 	{APHADDSW, yxm_q4, Pq4, [23]uint8{0x03}},
+ 	{APHADDW, yxm_q4, Pq4, [23]uint8{0x01}},
+@@ -1353,7 +1327,6 @@ var optab =
+ 	{APMOVZXWD, yxm_q4, Pq4, [23]uint8{0x33}},
+ 	{APMOVZXWQ, yxm_q4, Pq4, [23]uint8{0x34}},
+ 	{APMULDQ, yxm_q4, Pq4, [23]uint8{0x28}},
+-	{APMULHRW, ymfp, Px, [23]uint8{0xb7}},
+ 	{APMULHUW, ymm, Py1, [23]uint8{0xe4, Pe, 0xe4}},
+ 	{APMULHW, ymm, Py1, [23]uint8{0xe5, Pe, 0xe5}},
+ 	{APMULLD, yxm_q4, Pq4, [23]uint8{0x40}},
+@@ -1395,7 +1368,6 @@ var optab =
+ 	{APSUBUSB, yxm, Pe, [23]uint8{0xd8}},
+ 	{APSUBUSW, yxm, Pe, [23]uint8{0xd9}},
+ 	{APSUBW, yxm, Pe, [23]uint8{0xf9}},
+-	{APSWAPL, ymfp, Px, [23]uint8{0xbb}},
+ 	{APUNPCKHBW, ymm, Py1, [23]uint8{0x68, Pe, 0x68}},
+ 	{APUNPCKHLQ, ymm, Py1, [23]uint8{0x6a, Pe, 0x6a}},
+ 	{APUNPCKHQDQ, yxm, Pe, [23]uint8{0x6d}},
+@@ -1553,8 +1525,6 @@ var optab =
+ 	{AFCMOVNE, yfcmv, Px, [23]uint8{0xdb, 01}},
+ 	{AFCMOVNU, yfcmv, Px, [23]uint8{0xdb, 03}},
+ 	{AFCMOVUN, yfcmv, Px, [23]uint8{0xda, 03}},
+-	{AFCOMB, nil, 0, [23]uint8{}},
+-	{AFCOMBP, nil, 0, [23]uint8{}},
+ 	{AFCOMD, yfadd, Px, [23]uint8{0xdc, 02, 0xd8, 02, 0xdc, 02}},  /* botch */
+ 	{AFCOMDP, yfadd, Px, [23]uint8{0xdc, 03, 0xd8, 03, 0xdc, 03}}, /* botch */
+ 	{AFCOMDPP, ycompp, Px, [23]uint8{0xde, 03}},
+@@ -3533,15 +3503,6 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
+ 				ctxt.Andptr[0] = byte(p.To.Offset)
+ 				ctxt.Andptr = ctxt.Andptr[1:]
+ 
+-			case Zm_r_3d:
+-				ctxt.Andptr[0] = 0x0f
+-				ctxt.Andptr = ctxt.Andptr[1:]
+-				ctxt.Andptr[0] = 0x0f
+-				ctxt.Andptr = ctxt.Andptr[1:]
+-				asmand(ctxt, p, &p.From, &p.To)
+-				ctxt.Andptr[0] = byte(op)
+-				ctxt.Andptr = ctxt.Andptr[1:]
+-
+ 			case Zibm_r, Zibr_m:
+ 				for {
+ 					tmp1 := z
+@@ -4595,15 +4556,6 @@ func asmins(ctxt *obj.Link, p *obj.Prog) {
+ 	ctxt.Andptr = ctxt.And[:]
+ 	ctxt.Asmode = int(p.Mode)
+ 
+-	if p.As == obj.AUSEFIELD {
+-		r := obj.Addrel(ctxt.Cursym)
+-		r.Off = 0
+-		r.Siz = 0
+-		r.Sym = p.From.Sym
+-		r.Type = obj.R_USEFIELD
+-		return
+-	}
+-
+ 	if ctxt.Headtype == obj.Hnacl && p.Mode == 32 {
+ 		switch p.As {
+ 		case obj.ARET:
 diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go
-index 6495dfb..741f4ed 100644
+index f038883..b100830 100644
 --- a/src/cmd/internal/objfile/disasm.go
 +++ b/src/cmd/internal/objfile/disasm.go
 @@ -245,4 +245,5 @@ var byteOrders = map[string]binary.ByteOrder{
@@ -19672,7 +24829,7 @@ index ca8eabb..bf96661 100644
  	}
  
 diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
-index 563600d..3ed7b35 100644
+index a96b37a..96c3503 100644
 --- a/src/cmd/link/internal/ld/dwarf.go
 +++ b/src/cmd/link/internal/ld/dwarf.go
 @@ -1715,7 +1715,7 @@ func writelines() {
@@ -19748,7 +24905,7 @@ index 563600d..3ed7b35 100644
  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
  			} else {
  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
-@@ -2235,7 +2256,7 @@ func dwarfaddshstrings(shstrtab *LSym) {
+@@ -2237,7 +2258,7 @@ func dwarfaddshstrings(shstrtab *LSym) {
  	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
  	if Linkmode == LinkExternal {
  		switch Thearch.Thechar {
@@ -19757,7 +24914,7 @@ index 563600d..3ed7b35 100644
  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
-@@ -2288,7 +2309,7 @@ func dwarfaddelfsectionsyms() {
+@@ -2290,7 +2311,7 @@ func dwarfaddelfsectionsyms() {
  func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
  	sh := newElfShdr(elfstrdbg[elfstr])
  	switch Thearch.Thechar {
@@ -20128,8 +25285,73 @@ index 73d23c6..75dc7e2 100644
  	RV_CHECK_OVERFLOW = 1 << 8
  	RV_TYPE_MASK      = RV_CHECK_OVERFLOW - 1
  )
+diff --git a/src/cmd/link/internal/ld/pobj.go b/src/cmd/link/internal/ld/pobj.go
+index 808d377..9ec14c2 100644
+--- a/src/cmd/link/internal/ld/pobj.go
++++ b/src/cmd/link/internal/ld/pobj.go
+@@ -119,33 +119,6 @@ func Ldmain() {
+ 	obj.Flagstr("memprofile", "write memory profile to `file`", &memprofile)
+ 	obj.Flagint64("memprofilerate", "set runtime.MemProfileRate to `rate`", &memprofilerate)
+ 
+-	// Clumsy hack to preserve old two-argument -X name val syntax for old scripts.
+-	// Rewrite that syntax into new syntax -X name=val.
+-	// TODO(rsc): Delete this hack in Go 1.6 or later.
+-	var args []string
+-	for i := 0; i < len(os.Args); i++ {
+-		arg := os.Args[i]
+-		if (arg == "-X" || arg == "--X") && i+2 < len(os.Args) && !strings.Contains(os.Args[i+1], "=") {
+-			fmt.Fprintf(os.Stderr, "link: warning: option %s %s %s may not work in future releases; use %s %s=%s\n",
+-				arg, os.Args[i+1], os.Args[i+2],
+-				arg, os.Args[i+1], os.Args[i+2])
+-			args = append(args, arg)
+-			args = append(args, os.Args[i+1]+"="+os.Args[i+2])
+-			i += 2
+-			continue
+-		}
+-		if (strings.HasPrefix(arg, "-X=") || strings.HasPrefix(arg, "--X=")) && i+1 < len(os.Args) && strings.Count(arg, "=") == 1 {
+-			fmt.Fprintf(os.Stderr, "link: warning: option %s %s may not work in future releases; use %s=%s\n",
+-				arg, os.Args[i+1],
+-				arg, os.Args[i+1])
+-			args = append(args, arg+"="+os.Args[i+1])
+-			i++
+-			continue
+-		}
+-		args = append(args, arg)
+-	}
+-	os.Args = args
+-
+ 	obj.Flagparse(usage)
+ 
+ 	startProfile()
+diff --git a/src/cmd/link/internal/ld/sym.go b/src/cmd/link/internal/ld/sym.go
+index 731f3ed..6122b85 100644
+--- a/src/cmd/link/internal/ld/sym.go
++++ b/src/cmd/link/internal/ld/sym.go
+@@ -34,8 +34,6 @@ package ld
+ import (
+ 	"cmd/internal/obj"
+ 	"log"
+-	"os"
+-	"path/filepath"
+ 	"strconv"
+ )
+ 
+@@ -70,13 +68,6 @@ func linknew(arch *LinkArch) *Link {
+ 		log.Fatalf("invalid goarch %s (want %s)", p, arch.Name)
+ 	}
+ 
+-	var buf string
+-	buf, _ = os.Getwd()
+-	if buf == "" {
+-		buf = "/???"
+-	}
+-	buf = filepath.ToSlash(buf)
+-
+ 	ctxt.Headtype = headtype(obj.Getgoos())
+ 	if ctxt.Headtype < 0 {
+ 		log.Fatalf("unknown goos %s", obj.Getgoos())
 diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
-index 3e6169e..78198eb 100644
+index 3e6169e..9416d1e 100644
 --- a/src/cmd/link/internal/ld/symtab.go
 +++ b/src/cmd/link/internal/ld/symtab.go
 @@ -67,7 +67,7 @@ func putelfstr(s string) int {
@@ -20141,7 +25363,19 @@ index 3e6169e..78198eb 100644
  		Thearch.Lput(uint32(off))
  		Cput(uint8(info))
  		Cput(uint8(other))
-@@ -562,6 +562,7 @@ func symtab() {
+@@ -215,6 +215,11 @@ func Asmelfsym() {
+ 
+ 	dwarfaddelfsectionsyms()
+ 
++	// Some linkers will add a FILE sym if one is not present.
++	// Avoid having the working directory inserted into the symbol table.
++	putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
++	numelfsym++
++
+ 	elfbind = STB_LOCAL
+ 	genasmsym(putelfsym)
+ 
+@@ -562,6 +567,7 @@ func symtab() {
  		adduint(Ctxt, moduledata, uint64(len(Ctxt.Shlibs)))
  		adduint(Ctxt, moduledata, uint64(len(Ctxt.Shlibs)))
  	}
@@ -21023,72 +26257,5558 @@ index 63df8de..0122bda 100644
 +		s390x.Main()
  	}
  }
-diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
-index 8ceaba0..cd55e16 100644
---- a/src/cmd/objdump/objdump_test.go
-+++ b/src/cmd/objdump/objdump_test.go
-@@ -107,6 +107,8 @@ func TestDisasm(t *testing.T) {
- 		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
- 	case "mips64", "mips64le":
- 		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
-+	case "s390x":
-+		t.Skipf("skipping on %s", runtime.GOARCH)
- 	}
- 	testDisasm(t)
- }
-@@ -123,6 +125,8 @@ func TestDisasmExtld(t *testing.T) {
- 		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
- 	case "mips64", "mips64le":
- 		t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH)
-+	case "s390x":
-+		t.Skipf("skipping on %s", runtime.GOARCH)
- 	}
- 	// TODO(jsing): Reenable once openbsd/arm has external linking support.
- 	if runtime.GOOS == "openbsd" && runtime.GOARCH == "arm" {
-diff --git a/src/cmd/vet/asmdecl.go b/src/cmd/vet/asmdecl.go
-index e4a9871..025d3e0 100644
---- a/src/cmd/vet/asmdecl.go
-+++ b/src/cmd/vet/asmdecl.go
-@@ -65,6 +65,7 @@ var (
- 	asmArchAmd64p32 = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
- 	asmArchPpc64    = asmArch{"ppc64", 8, 8, 8, true, "R1", true}
- 	asmArchPpc64LE  = asmArch{"ppc64le", 8, 8, 8, false, "R1", true}
-+	asmArchS390x    = asmArch{"s390x", 8, 8, 8, true, "R15", true}
- 
- 	arches = []*asmArch{
- 		&asmArch386,
-@@ -74,6 +75,7 @@ var (
- 		&asmArchAmd64p32,
- 		&asmArchPpc64,
- 		&asmArchPpc64LE,
-+		&asmArchS390x,
- 	}
- )
- 
-diff --git a/src/crypto/aes/asm_s390x.s b/src/crypto/aes/asm_s390x.s
+diff --git a/src/cmd/newlink/auto.go b/src/cmd/newlink/auto.go
 new file mode 100644
-index 0000000..c9cf166
+index 0000000..21f6d60
 --- /dev/null
-+++ b/src/crypto/aes/asm_s390x.s
-@@ -0,0 +1,97 @@
-+// Copyright 2016 The Go Authors. All rights reserved.
++++ b/src/cmd/newlink/auto.go
+@@ -0,0 +1,117 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
 +
-+#include "textflag.h"
++// Automatic symbol generation.
 +
-+// func hasAsm() bool
-+// returns whether the AES-128, AES-192 and AES-256
-+// cipher message functions are supported.
-+TEXT ·hasAsm(SB),NOSPLIT,$16-1
-+	XOR    R0, R0 // set function code to 0 (query)
-+	LA     8(R15), R1
-+	WORD   $0xB92E0024 // KM-Query
++// TODO(rsc): Handle go.typelink, go.track symbols.
++// TODO(rsc): Do not handle $f64. and $f32. symbols. Instead, generate those
++// from the compiler and assemblers as dupok data, and then remove autoData below.
++package main
 +
-+	// check if bits 18-20 are set
-+	MOVD   8(R15), R2
-+	SRD    $40, R2
-+	AND    $0x38, R2  // mask bits 18-20 (00111000)
++import (
++	"cmd/internal/goobj"
++	"strconv"
++	"strings"
++)
++
++// linkerDefined lists the symbols supplied by other parts of the linker
++// (runtime.go and layout.go).
++var linkerDefined = map[string]bool{
++	"runtime.bss":        true,
++	"runtime.data":       true,
++	"runtime.ebss":       true,
++	"runtime.edata":      true,
++	"runtime.efunctab":   true,
++	"runtime.end":        true,
++	"runtime.enoptrbss":  true,
++	"runtime.enoptrdata": true,
++	"runtime.erodata":    true,
++	"runtime.etext":      true,
++	"runtime.etypelink":  true,
++	"runtime.functab":    true,
++	"runtime.gcbss":      true,
++	"runtime.gcdata":     true,
++	"runtime.noptrbss":   true,
++	"runtime.noptrdata":  true,
++	"runtime.pclntab":    true,
++	"runtime.rodata":     true,
++	"runtime.text":       true,
++	"runtime.typelink":   true,
++}
++
++// isAuto reports whether sym is an automatically-generated data or constant symbol.
++func (p *Prog) isAuto(sym goobj.SymID) bool {
++	return strings.HasPrefix(sym.Name, "go.weak.") ||
++		strings.HasPrefix(sym.Name, "$f64.") ||
++		strings.HasPrefix(sym.Name, "$f32.") ||
++		linkerDefined[sym.Name]
++}
++
++// autoData defines the automatically generated data symbols needed by p.
++func (p *Prog) autoData() {
++	for sym := range p.Missing {
++		switch {
++		// Floating-point constants that need to be loaded from memory are
++		// written as $f64.{16 hex digits} or $f32.{8 hex digits}; the hex digits
++		// give the IEEE bit pattern of the constant. As far as the layout into
++		// memory is concerned, we interpret these as uint64 or uint32 constants.
++		case strings.HasPrefix(sym.Name, "$f64."), strings.HasPrefix(sym.Name, "$f32."):
++			size := 64
++			if sym.Name[2:4] == "32" {
++				size = 32
++			}
++			delete(p.Missing, sym)
++			fbits, err := strconv.ParseUint(sym.Name[len("$f64."):], 16, size)
++			if err != nil {
++				p.errorf("unexpected floating point symbol %s", sym)
++				continue
++			}
++			data := make([]byte, size/8)
++			if size == 64 {
++				p.byteorder.PutUint64(data, fbits)
++			} else {
++				p.byteorder.PutUint32(data, uint32(fbits))
++			}
++			p.addSym(&Sym{
++				Sym: &goobj.Sym{
++					SymID: sym,
++					Kind:  goobj.SRODATA,
++					Size:  size / 8,
++				},
++				Bytes: data,
++			})
++		}
++	}
++}
++
++// autoConst defines the automatically generated constant symbols needed by p.
++func (p *Prog) autoConst() {
++	for sym := range p.Missing {
++		switch {
++		case strings.HasPrefix(sym.Name, "go.weak."):
++			// weak symbol resolves to actual symbol if present, or else nil.
++			delete(p.Missing, sym)
++			targ := sym
++			targ.Name = sym.Name[len("go.weak."):]
++			var addr Addr
++			if s := p.Syms[targ]; s != nil {
++				addr = s.Addr
++			}
++			p.defineConst(sym.Name, addr)
++		}
++	}
++}
++
++// defineConst defines a new symbol with the given name and constant address.
++func (p *Prog) defineConst(name string, addr Addr) {
++	sym := goobj.SymID{Name: name}
++	p.addSym(&Sym{
++		Sym: &goobj.Sym{
++			SymID: sym,
++			Kind:  goobj.SCONST,
++		},
++		Package: nil,
++		Addr:    addr,
++	})
++}
+diff --git a/src/cmd/newlink/auto_test.go b/src/cmd/newlink/auto_test.go
+new file mode 100644
+index 0000000..f99e097
+--- /dev/null
++++ b/src/cmd/newlink/auto_test.go
+@@ -0,0 +1,72 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Test for auto-generated symbols.
++
++// There is no test for $f64. and $f32. symbols, because those are
++// not possible to write in the assembler syntax. Instead of changing
++// the assembler to allow that, we plan to change the compilers
++// not to generate such symbols (plain dupok data is sufficient).
++
++package main
++
++import (
++	"bytes"
++	"cmd/internal/goobj"
++	"testing"
++)
++
++// Each test case is an object file, generated from a corresponding .s file.
++// The image of the autotab symbol should be a sequence of pairs of
++// identical 8-byte sequences.
++var autoTests = []string{
++	"testdata/autosection.6",
++	"testdata/autoweak.6",
++}
++
++func TestAuto(t *testing.T) {
++	for _, obj := range autoTests {
++		p := Prog{GOOS: "darwin", GOARCH: "amd64", StartSym: "start"}
++		p.omitRuntime = true
++		p.Error = func(s string) { t.Error(s) }
++		var buf bytes.Buffer
++		p.link(&buf, obj)
++		if p.NumError > 0 {
++			continue // already reported
++		}
++
++		const name = "autotab"
++		sym := p.Syms[goobj.SymID{Name: name}]
++		if sym == nil {
++			t.Errorf("%s is missing %s symbol", obj, name)
++			return
++		}
++		if sym.Size == 0 {
++			return
++		}
++
++		seg := sym.Section.Segment
++		off := sym.Addr - seg.VirtAddr
++		data := seg.Data[off : off+Addr(sym.Size)]
++		if len(data)%16 != 0 {
++			t.Errorf("%s: %s.Size = %d, want multiple of 16", obj, name, len(data))
++			return
++		}
++	Data:
++		for i := 0; i < len(data); i += 16 {
++			have := p.byteorder.Uint64(data[i : i+8])
++			want := p.byteorder.Uint64(data[i+8 : i+16])
++			if have != want {
++				// Look for relocation so we can explain what went wrong.
++				for _, r := range sym.Reloc {
++					if r.Offset == i {
++						t.Errorf("%s: %s+%#x: %s: have %#x want %#x", obj, name, i, r.Sym, have, want)
++						continue Data
++					}
++				}
++				t.Errorf("%s: %s+%#x: have %#x want %#x", obj, name, i, have, want)
++			}
++		}
++	}
++}
+diff --git a/src/cmd/newlink/dead.go b/src/cmd/newlink/dead.go
+new file mode 100644
+index 0000000..ee23a61
+--- /dev/null
++++ b/src/cmd/newlink/dead.go
+@@ -0,0 +1,74 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Removal of dead code and data.
++
++package main
++
++import "cmd/internal/goobj"
++
++// dead removes unreachable code and data from the program.
++// It is basically a mark-sweep garbage collection: traverse all the
++// symbols reachable from the entry (startSymID) and then delete
++// the rest.
++func (p *Prog) dead() {
++	p.Dead = make(map[goobj.SymID]bool)
++	reachable := make(map[goobj.SymID]bool)
++	p.walkDead(p.startSym, reachable)
++
++	for sym := range p.Syms {
++		if !reachable[sym] {
++			delete(p.Syms, sym)
++			p.Dead[sym] = true
++		}
++	}
++
++	for sym := range p.Missing {
++		if !reachable[sym] {
++			delete(p.Missing, sym)
++			p.Dead[sym] = true
++		}
++	}
++
++	p.SymOrder = removeDead(p.SymOrder, reachable)
++
++	for _, pkg := range p.Packages {
++		pkg.Syms = removeDead(pkg.Syms, reachable)
++	}
++}
++
++// walkDead traverses the symbols reachable from sym, adding them to reachable.
++// The caller has verified that reachable[sym] = false.
++func (p *Prog) walkDead(sym goobj.SymID, reachable map[goobj.SymID]bool) {
++	reachable[sym] = true
++	s := p.Syms[sym]
++	if s == nil {
++		return
++	}
++	for i := range s.Reloc {
++		r := &s.Reloc[i]
++		if !reachable[r.Sym] {
++			p.walkDead(r.Sym, reachable)
++		}
++	}
++	if s.Func != nil {
++		for _, fdata := range s.Func.FuncData {
++			if fdata.Sym.Name != "" && !reachable[fdata.Sym] {
++				p.walkDead(fdata.Sym, reachable)
++			}
++		}
++	}
++}
++
++// removeDead removes unreachable (dead) symbols from syms,
++// returning a shortened slice using the same underlying array.
++func removeDead(syms []*Sym, reachable map[goobj.SymID]bool) []*Sym {
++	keep := syms[:0]
++	for _, sym := range syms {
++		if reachable[sym.SymID] {
++			keep = append(keep, sym)
++		}
++	}
++	return keep
++}
+diff --git a/src/cmd/newlink/dead_test.go b/src/cmd/newlink/dead_test.go
+new file mode 100644
+index 0000000..eb34d05
+--- /dev/null
++++ b/src/cmd/newlink/dead_test.go
+@@ -0,0 +1,97 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"cmd/internal/goobj"
++	"reflect"
++	"strings"
++	"testing"
++)
++
++// Each test case is an object file, generated from a corresponding .s file.
++// The symbols in the object file with a dead_ prefix are the ones that
++// should be removed from the program.
++var deadTests = []string{
++	"testdata/dead.6",
++}
++
++func TestDead(t *testing.T) {
++	for _, obj := range deadTests {
++		p := Prog{GOOS: "darwin", GOARCH: "amd64", StartSym: "start"}
++		p.omitRuntime = true
++		p.Error = func(s string) { t.Error(s) }
++		p.init()
++		p.scan(obj)
++		if p.NumError > 0 {
++			continue // already reported
++		}
++		origSyms := copyMap(p.Syms)
++		origMissing := copyMap(p.Missing)
++		origSymOrder := copySlice(p.SymOrder)
++		origPkgSyms := copySlice(p.Packages["main"].Syms)
++		p.dead()
++		checkDeadMap(t, obj, "p.Syms", origSyms, p.Syms)
++		checkDeadMap(t, obj, "p.Missing", origMissing, p.Missing)
++		checkDeadSlice(t, obj, "p.SymOrder", origSymOrder, p.SymOrder)
++		checkDeadSlice(t, obj, `p.Packages["main"].Syms`, origPkgSyms, p.Packages["main"].Syms)
++	}
++}
++
++func copyMap(m interface{}) interface{} {
++	v := reflect.ValueOf(m)
++	out := reflect.MakeMap(v.Type())
++	for _, key := range v.MapKeys() {
++		out.SetMapIndex(key, v.MapIndex(key))
++	}
++	return out.Interface()
++}
++
++func checkDeadMap(t *testing.T, obj, name string, old, new interface{}) {
++	vold := reflect.ValueOf(old)
++	vnew := reflect.ValueOf(new)
++	for _, vid := range vold.MapKeys() {
++		id := vid.Interface().(goobj.SymID)
++		if strings.HasPrefix(id.Name, "dead_") {
++			if vnew.MapIndex(vid).IsValid() {
++				t.Errorf("%s: %s contains unnecessary symbol %s", obj, name, id)
++			}
++		} else {
++			if !vnew.MapIndex(vid).IsValid() {
++				t.Errorf("%s: %s is missing symbol %s", obj, name, id)
++			}
++		}
++	}
++	for _, vid := range vnew.MapKeys() {
++		id := vid.Interface().(goobj.SymID)
++		if !vold.MapIndex(vid).IsValid() {
++			t.Errorf("%s: %s contains unexpected symbol %s", obj, name, id)
++		}
++	}
++}
++
++func copySlice(x []*Sym) (out []*Sym) {
++	return append(out, x...)
++}
++
++func checkDeadSlice(t *testing.T, obj, name string, old, new []*Sym) {
++	for i, s := range old {
++		if strings.HasPrefix(s.Name, "dead_") {
++			continue
++		}
++		if len(new) == 0 {
++			t.Errorf("%s: %s is missing symbol %s\nhave%v\nwant%v", obj, name, s, new, old[i:])
++			return
++		}
++		if new[0].SymID != s.SymID {
++			t.Errorf("%s: %s is incorrect: have %s, want %s\nhave%v\nwant%v", obj, name, new[0].SymID, s.SymID, new, old[i:])
++			return
++		}
++		new = new[1:]
++	}
++	if len(new) > 0 {
++		t.Errorf("%s: %s has unexpected symbols: %v", obj, name, new)
++	}
++}
+diff --git a/src/cmd/newlink/debug.go b/src/cmd/newlink/debug.go
+new file mode 100644
+index 0000000..ee20644
+--- /dev/null
++++ b/src/cmd/newlink/debug.go
+@@ -0,0 +1,11 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Generation of debug data structures (in the executable but not mapped at run time).
++// See also runtime.go.
++
++package main
++
++func (p *Prog) debug() {
++}
+diff --git a/src/cmd/newlink/hex_test.go b/src/cmd/newlink/hex_test.go
+new file mode 100644
+index 0000000..b76b266
+--- /dev/null
++++ b/src/cmd/newlink/hex_test.go
+@@ -0,0 +1,74 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"encoding/hex"
++	"fmt"
++	"io/ioutil"
++	"regexp"
++	"strconv"
++	"strings"
++	"testing"
++)
++
++// mustParseHexdumpFile returns a block of data generated by
++// parsing the hex dump in the named file.
++// If the file cannot be read or does not contain a valid hex dump,
++// mustParseHexdumpFile calls t.Fatal.
++func mustParseHexdumpFile(t *testing.T, file string) []byte {
++	hex, err := ioutil.ReadFile(file)
++	if err != nil {
++		t.Fatal(err)
++	}
++	data, err := parseHexdump(string(hex))
++	if err != nil {
++		t.Fatal(err)
++	}
++	return data
++}
++
++// parseHexdump parses the hex dump in text, which should be the
++// output of "hexdump -C" or Plan 9's "xd -b",
++// and returns the original data used to produce the dump.
++// It is meant to enable storing golden binary files as text, so that
++// changes to the golden files can be seen during code reviews.
++func parseHexdump(text string) ([]byte, error) {
++	var out []byte
++	for _, line := range strings.Split(text, "\n") {
++		if i := strings.Index(line, "|"); i >= 0 { // remove text dump
++			line = line[:i]
++		}
++		f := strings.Fields(line)
++		if len(f) > 1+16 {
++			return nil, fmt.Errorf("parsing hex dump: too many fields on line %q", line)
++		}
++		if len(f) == 0 || len(f) == 1 && f[0] == "*" { // all zeros block omitted
++			continue
++		}
++		addr64, err := strconv.ParseUint(f[0], 16, 0)
++		if err != nil {
++			return nil, fmt.Errorf("parsing hex dump: invalid address %q", f[0])
++		}
++		addr := int(addr64)
++		if len(out) < addr {
++			out = append(out, make([]byte, addr-len(out))...)
++		}
++		for _, x := range f[1:] {
++			val, err := strconv.ParseUint(x, 16, 8)
++			if err != nil {
++				return nil, fmt.Errorf("parsing hexdump: invalid hex byte %q", x)
++			}
++			out = append(out, byte(val))
++		}
++	}
++	return out, nil
++}
++
++func hexdump(data []byte) string {
++	text := hex.Dump(data) + fmt.Sprintf("%08x\n", len(data))
++	text = regexp.MustCompile(`\n([0-9a-f]+(\s+00){16}.*\n)+`).ReplaceAllString(text, "\n*\n")
++	return text
++}
+diff --git a/src/cmd/newlink/layout.go b/src/cmd/newlink/layout.go
+new file mode 100644
+index 0000000..d5c291e
+--- /dev/null
++++ b/src/cmd/newlink/layout.go
+@@ -0,0 +1,180 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Executable image layout - address assignment.
++
++package main
++
++import (
++	"cmd/internal/goobj"
++)
++
++// A layoutSection describes a single section to add to the
++// final executable. Go binaries only have a fixed set of possible
++// sections, and the symbol kind determines the section.
++type layoutSection struct {
++	Segment string
++	Section string
++	Kind    goobj.SymKind
++	Index   int
++}
++
++// layout defines the layout of the generated Go executable.
++// The order of entries here is the order in the executable.
++// Entries with the same Segment name must be contiguous.
++var layout = []layoutSection{
++	{Segment: "text", Section: "text", Kind: goobj.STEXT},
++	{Segment: "rodata", Section: "rodata", Kind: goobj.SRODATA},
++	{Segment: "rodata", Section: "functab", Kind: goobj.SPCLNTAB},
++	{Segment: "rodata", Section: "typelink", Kind: goobj.STYPELINK},
++	{Segment: "data", Section: "noptrdata", Kind: goobj.SNOPTRDATA},
++	{Segment: "data", Section: "data", Kind: goobj.SDATA},
++	{Segment: "data", Section: "bss", Kind: goobj.SBSS},
++	{Segment: "data", Section: "noptrbss", Kind: goobj.SNOPTRBSS},
++
++	// Later:
++	//	{"rodata", "type", goobj.STYPE},
++	//	{"rodata", "string", goobj.SSTRING},
++	//	{"rodata", "gostring", goobj.SGOSTRING},
++	//	{"rodata", "gofunc", goobj.SGOFUNC},
++}
++
++// layoutByKind maps from SymKind to an entry in layout.
++var layoutByKind []*layoutSection
++
++func init() {
++	// Build index from symbol type to layout entry.
++	max := 0
++	for _, sect := range layout {
++		if max <= int(sect.Kind) {
++			max = int(sect.Kind) + 1
++		}
++	}
++	layoutByKind = make([]*layoutSection, max)
++	for i := range layout {
++		sect := &layout[i]
++		layoutByKind[sect.Kind] = sect
++		sect.Index = i
++	}
++}
++
++// layout arranges symbols into sections and sections into segments,
++// and then it assigns addresses to segments, sections, and symbols.
++func (p *Prog) layout() {
++	sections := make([]*Section, len(layout))
++
++	// Assign symbols to sections using index, creating sections as needed.
++	// Could keep sections separated by type during input instead.
++	for _, sym := range p.SymOrder {
++		kind := sym.Kind
++		if kind < 0 || int(kind) >= len(layoutByKind) || layoutByKind[kind] == nil {
++			p.errorf("%s: unexpected symbol kind %v", sym.SymID, kind)
++			continue
++		}
++		lsect := layoutByKind[kind]
++		sect := sections[lsect.Index]
++		if sect == nil {
++			sect = &Section{
++				Name:  lsect.Section,
++				Align: 1,
++			}
++			sections[lsect.Index] = sect
++		}
++		if sym.Data.Size > 0 || len(sym.Bytes) > 0 {
++			sect.InFile = true
++		}
++		sym.Section = sect
++		sect.Syms = append(sect.Syms, sym)
++
++		// TODO(rsc): Incorporate alignment information.
++		// First that information needs to be added to the object files.
++		//
++		// if sect.Align < Addr(sym.Align) {
++		//	sect.Align = Addr(sym.Align)
++		// }
++	}
++
++	// Assign sections to segments, creating segments as needed.
++	var seg *Segment
++	for i, sect := range sections {
++		if sect == nil {
++			continue
++		}
++		segName := layout[i].Segment
++
++		// Special case: Mach-O does not support "rodata" segment,
++		// so store read-only data in text segment.
++		if p.GOOS == "darwin" && segName == "rodata" {
++			segName = "text"
++		}
++
++		if seg == nil || seg.Name != segName {
++			seg = &Segment{
++				Name: segName,
++			}
++			p.Segments = append(p.Segments, seg)
++		}
++		sect.Segment = seg
++		seg.Sections = append(seg.Sections, sect)
++	}
++
++	// Assign addresses.
++
++	// TODO(rsc): This choice needs to be informed by both
++	// the formatter and the target architecture.
++	// And maybe eventually a command line flag (sigh).
++	const segAlign = 4096
++
++	// TODO(rsc): Use a larger amount on most systems, which will let the
++	// compiler eliminate more nil checks.
++	if p.UnmappedSize == 0 {
++		p.UnmappedSize = segAlign
++	}
++
++	// TODO(rsc): addr := Addr(0) when generating a shared library or PIE.
++	addr := p.UnmappedSize
++
++	// Account for initial file header.
++	hdrVirt, hdrFile := p.formatter.headerSize(p)
++	addr += hdrVirt
++
++	// Assign addresses to segments, sections, symbols.
++	// Assign sizes to segments, sections.
++	startVirt := addr
++	startFile := hdrFile
++	for _, seg := range p.Segments {
++		addr = round(addr, segAlign)
++		seg.VirtAddr = addr
++		seg.FileOffset = startFile + seg.VirtAddr - startVirt
++		for _, sect := range seg.Sections {
++			addr = round(addr, sect.Align)
++			sect.VirtAddr = addr
++			for _, sym := range sect.Syms {
++				// TODO(rsc): Respect alignment once we have that information.
++				sym.Addr = addr
++				addr += Addr(sym.Size)
++			}
++			sect.Size = addr - sect.VirtAddr
++			if sect.InFile {
++				seg.FileSize = addr - seg.VirtAddr
++			}
++		}
++		seg.VirtSize = addr - seg.VirtAddr
++	}
++
++	// Define symbols for section names.
++	var progEnd Addr
++	for i, sect := range sections {
++		name := layout[i].Section
++		var start, end Addr
++		if sect != nil {
++			start = sect.VirtAddr
++			end = sect.VirtAddr + sect.Size
++		}
++		p.defineConst("runtime."+name, start)
++		p.defineConst("runtime.e"+name, end)
++		progEnd = end
++	}
++	p.defineConst("runtime.end", progEnd)
++}
+diff --git a/src/cmd/newlink/layout_test.go b/src/cmd/newlink/layout_test.go
+new file mode 100644
+index 0000000..e5513af
+--- /dev/null
++++ b/src/cmd/newlink/layout_test.go
+@@ -0,0 +1,45 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"bytes"
++	"strings"
++	"testing"
++)
++
++func TestLayout(t *testing.T) {
++	p := Prog{GOOS: "darwin", GOARCH: "amd64", StartSym: "text_start"}
++	p.omitRuntime = true
++	p.Error = func(s string) { t.Error(s) }
++	var buf bytes.Buffer
++	const obj = "testdata/layout.6"
++	p.link(&buf, obj)
++	if p.NumError > 0 {
++		return // already reported
++	}
++	if len(p.Dead) > 0 {
++		t.Errorf("%s: unexpected dead symbols %v", obj, p.Dead)
++		return
++	}
++
++	for _, sym := range p.SymOrder {
++		if p.isAuto(sym.SymID) {
++			continue
++		}
++		if sym.Section == nil {
++			t.Errorf("%s: symbol %s is missing section", obj, sym)
++			continue
++		}
++		i := strings.Index(sym.Name, "_")
++		if i < 0 {
++			t.Errorf("%s: unexpected symbol %s", obj, sym)
++			continue
++		}
++		if sym.Section.Name != sym.Name[:i] {
++			t.Errorf("%s: symbol %s in section %s, want %s", obj, sym, sym.Section.Name, sym.Name[:i])
++		}
++	}
++}
+diff --git a/src/cmd/newlink/link_test.go b/src/cmd/newlink/link_test.go
+new file mode 100644
+index 0000000..b5ae15f
+--- /dev/null
++++ b/src/cmd/newlink/link_test.go
+@@ -0,0 +1,35 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"bytes"
++	"cmd/internal/goobj"
++	"io/ioutil"
++	"testing"
++)
++
++func TestLinkHello(t *testing.T) {
++	p := &Prog{
++		GOOS:     "darwin",
++		GOARCH:   "amd64",
++		Error:    func(s string) { t.Error(s) },
++		StartSym: "_rt0_go",
++	}
++	var buf bytes.Buffer
++	p.link(&buf, "testdata/hello.6")
++	if p.NumError > 0 {
++		return
++	}
++	if p.Syms[goobj.SymID{"_rt0_go", 0}] == nil || p.Syms[goobj.SymID{"hello", 1}] == nil {
++		t.Errorf("Syms = %v, want at least [_rt0_go hello<1>]", p.Syms)
++	}
++
++	// uncomment to leave file behind for execution:
++	if false {
++		ioutil.WriteFile("a.out", buf.Bytes(), 0777)
++	}
++	checkGolden(t, buf.Bytes(), "testdata/link.hello.darwin.amd64")
++}
+diff --git a/src/cmd/newlink/load.go b/src/cmd/newlink/load.go
+new file mode 100644
+index 0000000..50602b8
+--- /dev/null
++++ b/src/cmd/newlink/load.go
+@@ -0,0 +1,108 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Loading of code and data fragments from package files into final image.
++
++package main
++
++import (
++	"cmd/internal/obj"
++	"os"
++)
++
++// load allocates segment images, populates them with data
++// read from package files, and applies relocations to the data.
++func (p *Prog) load() {
++	// TODO(rsc): mmap the output file and store the data directly.
++	// That will make writing the output file more efficient.
++	for _, seg := range p.Segments {
++		seg.Data = make([]byte, seg.FileSize)
++	}
++	for _, pkg := range p.Packages {
++		p.loadPackage(pkg)
++	}
++}
++
++// loadPackage loads and relocates data for all the
++// symbols needed in the given package.
++func (p *Prog) loadPackage(pkg *Package) {
++	if pkg.File == "" {
++		// This "package" contains internally generated symbols only.
++		// All such symbols have a sym.Bytes field holding the actual data
++		// (if any), plus relocations.
++		for _, sym := range pkg.Syms {
++			if sym.Bytes == nil {
++				continue
++			}
++			seg := sym.Section.Segment
++			off := sym.Addr - seg.VirtAddr
++			data := seg.Data[off : off+Addr(sym.Size)]
++			copy(data, sym.Bytes)
++			p.relocateSym(sym, data)
++		}
++		return
++	}
++
++	// Package stored in file.
++	f, err := os.Open(pkg.File)
++	if err != nil {
++		p.errorf("%v", err)
++		return
++	}
++	defer f.Close()
++
++	// TODO(rsc): Mmap file into memory.
++
++	for _, sym := range pkg.Syms {
++		if sym.Data.Size == 0 {
++			continue
++		}
++		// TODO(rsc): If not using mmap, at least coalesce nearby reads.
++		if sym.Section == nil {
++			p.errorf("internal error: missing section for %s", sym.Name)
++		}
++		seg := sym.Section.Segment
++		off := sym.Addr - seg.VirtAddr
++		if off >= Addr(len(seg.Data)) || off+Addr(sym.Data.Size) > Addr(len(seg.Data)) {
++			p.errorf("internal error: allocated space for %s too small: %d bytes for %d+%d (%d)", sym, len(seg.Data), off, sym.Data.Size, sym.Size)
++		}
++		data := seg.Data[off : off+Addr(sym.Data.Size)]
++		_, err := f.ReadAt(data, sym.Data.Offset)
++		if err != nil {
++			p.errorf("reading %v: %v", sym.SymID, err)
++		}
++		p.relocateSym(sym, data)
++	}
++}
++
++// relocateSym applies relocations to sym's data.
++func (p *Prog) relocateSym(sym *Sym, data []byte) {
++	for i := range sym.Reloc {
++		r := &sym.Reloc[i]
++		targ := p.Syms[r.Sym]
++		if targ == nil {
++			p.errorf("%v: reference to undefined symbol %v", sym, r.Sym)
++			continue
++		}
++		val := targ.Addr + Addr(r.Add)
++		switch r.Type {
++		default:
++			p.errorf("%v: unknown relocation type %d", sym, r.Type)
++		case obj.R_ADDR, obj.R_CALLIND:
++			// ok
++		case obj.R_PCREL, obj.R_CALL:
++			val -= sym.Addr + Addr(r.Offset+r.Size)
++		}
++		frag := data[r.Offset : r.Offset+r.Size]
++		switch r.Size {
++		default:
++			p.errorf("%v: unknown relocation size %d", sym, r.Size)
++		case 4:
++			// TODO(rsc): Check for overflow?
++			p.byteorder.PutUint32(frag, uint32(val))
++		case 8:
++			p.byteorder.PutUint64(frag, uint64(val))
++		}
++	}
++}
+diff --git a/src/cmd/newlink/macho.go b/src/cmd/newlink/macho.go
+new file mode 100644
+index 0000000..4e5524b
+--- /dev/null
++++ b/src/cmd/newlink/macho.go
+@@ -0,0 +1,380 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Mach-O (Darwin) object file writing.
++
++package main
++
++import (
++	"debug/macho"
++	"encoding/binary"
++	"io"
++	"strings"
++)
++
++// machoFormat is the implementation of formatter.
++type machoFormat struct{}
++
++// machoHeader and friends are data structures
++// corresponding to the Mach-O file header
++// to be written to disk.
++
++const (
++	macho64Bit     = 1 << 24
++	machoSubCPU386 = 3
++)
++
++// machoArch describes a Mach-O target architecture.
++type machoArch struct {
++	CPU    uint32
++	SubCPU uint32
++}
++
++// machoHeader is the Mach-O file header.
++type machoHeader struct {
++	machoArch
++	FileType uint32
++	Loads    []*machoLoad
++	Segments []*machoSegment
++	p        *Prog // for reporting errors
++}
++
++// machoLoad is a Mach-O load command.
++type machoLoad struct {
++	Type uint32
++	Data []uint32
++}
++
++// machoSegment is a Mach-O segment.
++type machoSegment struct {
++	Name       string
++	VirtAddr   Addr
++	VirtSize   Addr
++	FileOffset Addr
++	FileSize   Addr
++	Prot1      uint32
++	Prot2      uint32
++	Flags      uint32
++	Sections   []*machoSection
++}
++
++// machoSection is a Mach-O section, inside a segment.
++type machoSection struct {
++	Name    string
++	Segment string
++	Addr    Addr
++	Size    Addr
++	Offset  uint32
++	Align   uint32
++	Reloc   uint32
++	Nreloc  uint32
++	Flags   uint32
++	Res1    uint32
++	Res2    uint32
++}
++
++// layout positions the segments and sections in p
++// to make room for the Mach-O file header.
++// That is, it edits their VirtAddr fields to adjust for the presence
++// of the Mach-O header at the beginning of the address space.
++func (machoFormat) headerSize(p *Prog) (virt, file Addr) {
++	var h machoHeader
++	h.init(p)
++	size := Addr(h.size())
++	size = round(size, 4096)
++	p.HeaderSize = size
++	return size, size
++}
++
++// write writes p to w as a Mach-O executable.
++// layout(p) must have already been called,
++// and the number, sizes, and addresses of the segments
++// and sections must not have been modified since the call.
++func (machoFormat) write(w io.Writer, p *Prog) {
++	var h machoHeader
++	h.init(p)
++	off := Addr(0)
++	enc := h.encode()
++	w.Write(enc)
++	off += Addr(len(enc))
++	for _, seg := range p.Segments {
++		if seg.FileOffset < off {
++			h.p.errorf("mach-o error: invalid file offset")
++		}
++		w.Write(make([]byte, int(seg.FileOffset-off)))
++		if seg.FileSize != Addr(len(seg.Data)) {
++			h.p.errorf("mach-o error: invalid file size")
++		}
++		w.Write(seg.Data)
++		off = seg.FileOffset + Addr(len(seg.Data))
++	}
++}
++
++// Conversion of Prog to macho data structures.
++
++// machoArches maps from GOARCH to machoArch.
++var machoArches = map[string]machoArch{
++	"amd64": {
++		CPU:    uint32(macho.CpuAmd64),
++		SubCPU: uint32(machoSubCPU386),
++	},
++}
++
++// init initializes the header h to describe p.
++func (h *machoHeader) init(p *Prog) {
++	h.p = p
++	h.Segments = nil
++	h.Loads = nil
++	var ok bool
++	h.machoArch, ok = machoArches[p.GOARCH]
++	if !ok {
++		p.errorf("mach-o: unknown target GOARCH %q", p.GOARCH)
++		return
++	}
++	h.FileType = uint32(macho.TypeExec)
++
++	mseg := h.addSegment(p, "__PAGEZERO", nil)
++	mseg.VirtSize = p.UnmappedSize
++
++	for _, seg := range p.Segments {
++		h.addSegment(p, "__"+strings.ToUpper(seg.Name), seg)
++	}
++
++	var data []uint32
++	switch h.CPU {
++	default:
++		p.errorf("mach-o: unknown cpu %#x for GOARCH %q", h.CPU, p.GOARCH)
++	case uint32(macho.CpuAmd64):
++		data = make([]uint32, 2+42)
++		data[0] = 4                  // thread type
++		data[1] = 42                 // word count
++		data[2+32] = uint32(p.Entry) // RIP register, in two parts
++		data[2+32+1] = uint32(p.Entry >> 32)
++	}
++
++	h.Loads = append(h.Loads, &machoLoad{
++		Type: uint32(macho.LoadCmdUnixThread),
++		Data: data,
++	})
++}
++
++// addSegment adds to h a Mach-O segment like seg with the given name.
++func (h *machoHeader) addSegment(p *Prog, name string, seg *Segment) *machoSegment {
++	mseg := &machoSegment{
++		Name: name,
++	}
++	h.Segments = append(h.Segments, mseg)
++	if seg == nil {
++		return mseg
++	}
++
++	mseg.VirtAddr = seg.VirtAddr
++	mseg.VirtSize = seg.VirtSize
++	mseg.FileOffset = round(seg.FileOffset, 4096)
++	mseg.FileSize = seg.FileSize
++
++	if name == "__TEXT" {
++		// Initially RWX, then just RX
++		mseg.Prot1 = 7
++		mseg.Prot2 = 5
++
++		// Text segment maps Mach-O header, needed by dynamic linker.
++		mseg.VirtAddr -= p.HeaderSize
++		mseg.VirtSize += p.HeaderSize
++		mseg.FileOffset -= p.HeaderSize
++		mseg.FileSize += p.HeaderSize
++	} else {
++		// RW
++		mseg.Prot1 = 3
++		mseg.Prot2 = 3
++	}
++
++	for _, sect := range seg.Sections {
++		h.addSection(mseg, seg, sect)
++	}
++	return mseg
++}
++
++// addSection adds to mseg a Mach-O section like sect, inside seg, with the given name.
++func (h *machoHeader) addSection(mseg *machoSegment, seg *Segment, sect *Section) {
++	msect := &machoSection{
++		Name:    "__" + sect.Name,
++		Segment: mseg.Name,
++		// Reloc: sect.RelocOffset,
++		// NumReloc: sect.RelocLen / 8,
++		Addr: sect.VirtAddr,
++		Size: sect.Size,
++	}
++	mseg.Sections = append(mseg.Sections, msect)
++
++	for 1<<msect.Align < sect.Align {
++		msect.Align++
++	}
++
++	if off := sect.VirtAddr - seg.VirtAddr; off < seg.FileSize {
++		// Data in file.
++		if sect.Size > seg.FileSize-off {
++			h.p.errorf("mach-o error: section crosses file boundary")
++		}
++		msect.Offset = uint32(seg.FileOffset + off)
++	} else {
++		// Zero filled.
++		msect.Flags |= 1
++	}
++
++	if sect.Name == "text" {
++		msect.Flags |= 0x400 // contains executable instructions
++	}
++}
++
++// A machoWriter helps write Mach-O headers.
++// It is basically a buffer with some helper routines for writing integers.
++type machoWriter struct {
++	dst   []byte
++	tmp   [8]byte
++	order binary.ByteOrder
++	is64  bool
++	p     *Prog
++}
++
++// if64 returns x if w is writing a 64-bit object file; otherwise it returns y.
++func (w *machoWriter) if64(x, y interface{}) interface{} {
++	if w.is64 {
++		return x
++	}
++	return y
++}
++
++// encode encodes each of the given arguments into the writer.
++// It encodes uint32, []uint32, uint64, and []uint64 by writing each value
++// in turn in the correct byte order for the output file.
++// It encodes an Addr as a uint64 if writing a 64-bit output file, or else as a uint32.
++// It encodes []byte and string by writing the raw bytes (no length prefix).
++// It skips nil values in the args list.
++func (w *machoWriter) encode(args ...interface{}) {
++	for _, arg := range args {
++		switch arg := arg.(type) {
++		default:
++			w.p.errorf("mach-o error: cannot encode %T", arg)
++		case nil:
++			// skip
++		case []byte:
++			w.dst = append(w.dst, arg...)
++		case string:
++			w.dst = append(w.dst, arg...)
++		case uint32:
++			w.order.PutUint32(w.tmp[:], arg)
++			w.dst = append(w.dst, w.tmp[:4]...)
++		case []uint32:
++			for _, x := range arg {
++				w.order.PutUint32(w.tmp[:], x)
++				w.dst = append(w.dst, w.tmp[:4]...)
++			}
++		case uint64:
++			w.order.PutUint64(w.tmp[:], arg)
++			w.dst = append(w.dst, w.tmp[:8]...)
++		case Addr:
++			if w.is64 {
++				w.order.PutUint64(w.tmp[:], uint64(arg))
++				w.dst = append(w.dst, w.tmp[:8]...)
++			} else {
++				if Addr(uint32(arg)) != arg {
++					w.p.errorf("mach-o error: truncating address %#x to uint32", arg)
++				}
++				w.order.PutUint32(w.tmp[:], uint32(arg))
++				w.dst = append(w.dst, w.tmp[:4]...)
++			}
++		}
++	}
++}
++
++// segmentSize returns the size of the encoding of seg in bytes.
++func (w *machoWriter) segmentSize(seg *machoSegment) int {
++	if w.is64 {
++		return 18*4 + 20*4*len(seg.Sections)
++	}
++	return 14*4 + 22*4*len(seg.Sections)
++}
++
++// zeroPad returns the string s truncated or padded with NULs to n bytes.
++func zeroPad(s string, n int) string {
++	if len(s) >= n {
++		return s[:n]
++	}
++	return s + strings.Repeat("\x00", n-len(s))
++}
++
++// size returns the encoded size of the header.
++func (h *machoHeader) size() int {
++	// Could write separate code, but encoding is cheap; encode and throw it away.
++	return len(h.encode())
++}
++
++// encode returns the Mach-O encoding of the header.
++func (h *machoHeader) encode() []byte {
++	w := &machoWriter{p: h.p}
++	w.is64 = h.CPU&macho64Bit != 0
++	w.order = w.p.byteorder
++
++	loadSize := 0
++	for _, seg := range h.Segments {
++		loadSize += w.segmentSize(seg)
++	}
++	for _, l := range h.Loads {
++		loadSize += 4 * (2 + len(l.Data))
++	}
++
++	w.encode(
++		w.if64(macho.Magic64, macho.Magic32),
++		uint32(h.CPU),
++		uint32(h.SubCPU),
++		uint32(h.FileType),
++		uint32(len(h.Loads)+len(h.Segments)),
++		uint32(loadSize),
++		uint32(1),
++		w.if64(uint32(0), nil),
++	)
++
++	for _, seg := range h.Segments {
++		w.encode(
++			w.if64(uint32(macho.LoadCmdSegment64), uint32(macho.LoadCmdSegment)),
++			uint32(w.segmentSize(seg)),
++			zeroPad(seg.Name, 16),
++			seg.VirtAddr,
++			seg.VirtSize,
++			seg.FileOffset,
++			seg.FileSize,
++			seg.Prot1,
++			seg.Prot2,
++			uint32(len(seg.Sections)),
++			seg.Flags,
++		)
++		for _, sect := range seg.Sections {
++			w.encode(
++				zeroPad(sect.Name, 16),
++				zeroPad(seg.Name, 16),
++				sect.Addr,
++				sect.Size,
++				sect.Offset,
++				sect.Align,
++				sect.Reloc,
++				sect.Nreloc,
++				sect.Flags,
++				sect.Res1,
++				sect.Res2,
++				w.if64(uint32(0), nil),
++			)
++		}
++	}
++
++	for _, load := range h.Loads {
++		w.encode(
++			load.Type,
++			uint32(4*(2+len(load.Data))),
++			load.Data,
++		)
++	}
++
++	return w.dst
++}
+diff --git a/src/cmd/newlink/macho_test.go b/src/cmd/newlink/macho_test.go
+new file mode 100644
+index 0000000..37c4418
+--- /dev/null
++++ b/src/cmd/newlink/macho_test.go
+@@ -0,0 +1,407 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"bytes"
++	"debug/macho"
++	"encoding/binary"
++	"fmt"
++	"io/ioutil"
++	"strings"
++	"testing"
++)
++
++// Test macho writing by checking that each generated prog can be written
++// and then read back using debug/macho to get the same prog.
++// Also check against golden testdata file.
++var machoWriteTests = []struct {
++	name   string
++	golden bool
++	prog   *Prog
++}{
++	// amd64 exit 9
++	{
++		name:   "exit9",
++		golden: true,
++		prog: &Prog{
++			GOARCH:       "amd64",
++			GOOS:         "darwin",
++			UnmappedSize: 0x1000,
++			Entry:        0x1000,
++			Segments: []*Segment{
++				{
++					Name:       "text",
++					VirtAddr:   0x1000,
++					VirtSize:   13,
++					FileOffset: 0,
++					FileSize:   13,
++					Data: []byte{
++						0xb8, 0x01, 0x00, 0x00, 0x02, // MOVL $0x2000001, AX
++						0xbf, 0x09, 0x00, 0x00, 0x00, // MOVL $9, DI
++						0x0f, 0x05, // SYSCALL
++						0xf4, // HLT
++					},
++					Sections: []*Section{
++						{
++							Name:     "text",
++							VirtAddr: 0x1000,
++							Size:     13,
++							Align:    64,
++						},
++					},
++				},
++			},
++		},
++	},
++
++	// amd64 write hello world & exit 9
++	{
++		name:   "hello",
++		golden: true,
++		prog: &Prog{
++			GOARCH:       "amd64",
++			GOOS:         "darwin",
++			UnmappedSize: 0x1000,
++			Entry:        0x1000,
++			Segments: []*Segment{
++				{
++					Name:       "text",
++					VirtAddr:   0x1000,
++					VirtSize:   35,
++					FileOffset: 0,
++					FileSize:   35,
++					Data: []byte{
++						0xb8, 0x04, 0x00, 0x00, 0x02, // MOVL $0x2000001, AX
++						0xbf, 0x01, 0x00, 0x00, 0x00, // MOVL $1, DI
++						0xbe, 0x00, 0x30, 0x00, 0x00, // MOVL $0x3000, SI
++						0xba, 0x0c, 0x00, 0x00, 0x00, // MOVL $12, DX
++						0x0f, 0x05, // SYSCALL
++						0xb8, 0x01, 0x00, 0x00, 0x02, // MOVL $0x2000001, AX
++						0xbf, 0x09, 0x00, 0x00, 0x00, // MOVL $9, DI
++						0x0f, 0x05, // SYSCALL
++						0xf4, // HLT
++					},
++					Sections: []*Section{
++						{
++							Name:     "text",
++							VirtAddr: 0x1000,
++							Size:     35,
++							Align:    64,
++						},
++					},
++				},
++				{
++					Name:       "data",
++					VirtAddr:   0x2000,
++					VirtSize:   12,
++					FileOffset: 0x1000,
++					FileSize:   12,
++					Data:       []byte("hello world\n"),
++					Sections: []*Section{
++						{
++							Name:     "data",
++							VirtAddr: 0x2000,
++							Size:     12,
++							Align:    64,
++						},
++					},
++				},
++			},
++		},
++	},
++
++	// amd64 write hello world from rodata & exit 0
++	{
++		name:   "helloro",
++		golden: true,
++		prog: &Prog{
++			GOARCH:       "amd64",
++			GOOS:         "darwin",
++			UnmappedSize: 0x1000,
++			Entry:        0x1000,
++			Segments: []*Segment{
++				{
++					Name:       "text",
++					VirtAddr:   0x1000,
++					VirtSize:   0x100c,
++					FileOffset: 0,
++					FileSize:   0x100c,
++					Data: concat(
++						[]byte{
++							0xb8, 0x04, 0x00, 0x00, 0x02, // MOVL $0x2000001, AX
++							0xbf, 0x01, 0x00, 0x00, 0x00, // MOVL $1, DI
++							0xbe, 0x00, 0x30, 0x00, 0x00, // MOVL $0x3000, SI
++							0xba, 0x0c, 0x00, 0x00, 0x00, // MOVL $12, DX
++							0x0f, 0x05, // SYSCALL
++							0xb8, 0x01, 0x00, 0x00, 0x02, // MOVL $0x2000001, AX
++							0xbf, 0x00, 0x00, 0x00, 0x00, // MOVL $0, DI
++							0x0f, 0x05, // SYSCALL
++							0xf4, // HLT
++						},
++						make([]byte, 0x1000-35),
++						[]byte("hello world\n"),
++					),
++					Sections: []*Section{
++						{
++							Name:     "text",
++							VirtAddr: 0x1000,
++							Size:     35,
++							Align:    64,
++						},
++						{
++							Name:     "rodata",
++							VirtAddr: 0x2000,
++							Size:     12,
++							Align:    64,
++						},
++					},
++				},
++			},
++		},
++	},
++}
++
++func concat(xs ...[]byte) []byte {
++	var out []byte
++	for _, x := range xs {
++		out = append(out, x...)
++	}
++	return out
++}
++
++func TestMachoWrite(t *testing.T) {
++	for _, tt := range machoWriteTests {
++		name := tt.prog.GOARCH + "." + tt.name
++		prog := cloneProg(tt.prog)
++		prog.init()
++		var f machoFormat
++		vsize, fsize := f.headerSize(prog)
++		shiftProg(prog, vsize, fsize)
++		var buf bytes.Buffer
++		f.write(&buf, prog)
++		if false { // enable to debug
++			ioutil.WriteFile("a.out", buf.Bytes(), 0777)
++		}
++		read, err := machoRead(machoArches[tt.prog.GOARCH], buf.Bytes())
++		if err != nil {
++			t.Errorf("%s: reading mach-o output:\n\t%v", name, err)
++			continue
++		}
++		diffs := diffProg(read, prog)
++		if diffs != nil {
++			t.Errorf("%s: mismatched prog:\n\t%s", name, strings.Join(diffs, "\n\t"))
++			continue
++		}
++		if !tt.golden {
++			continue
++		}
++		checkGolden(t, buf.Bytes(), "testdata/macho."+name)
++	}
++}
++
++// machoRead reads the mach-o file in data and returns a corresponding prog.
++func machoRead(arch machoArch, data []byte) (*Prog, error) {
++	f, err := macho.NewFile(bytes.NewReader(data))
++	if err != nil {
++		return nil, err
++	}
++
++	var errors []string
++	errorf := func(format string, args ...interface{}) {
++		errors = append(errors, fmt.Sprintf(format, args...))
++	}
++
++	magic := uint32(0xFEEDFACE)
++	if arch.CPU&macho64Bit != 0 {
++		magic |= 1
++	}
++	if f.Magic != magic {
++		errorf("header: Magic = %#x, want %#x", f.Magic, magic)
++	}
++	if f.Cpu != macho.CpuAmd64 {
++		errorf("header: CPU = %#x, want %#x", f.Cpu, macho.CpuAmd64)
++	}
++	if f.SubCpu != 3 {
++		errorf("header: SubCPU = %#x, want %#x", f.SubCpu, 3)
++	}
++	if f.Type != 2 {
++		errorf("header: FileType = %d, want %d", f.Type, 2)
++	}
++	if f.Flags != 1 {
++		errorf("header: Flags = %d, want %d", f.Flags, 1)
++	}
++
++	msects := f.Sections
++	var limit uint64
++	prog := new(Prog)
++	for _, load := range f.Loads {
++		switch load := load.(type) {
++		default:
++			errorf("unexpected macho load %T %x", load, load.Raw())
++
++		case macho.LoadBytes:
++			if len(load) < 8 || len(load)%4 != 0 {
++				errorf("unexpected load length %d", len(load))
++				continue
++			}
++			cmd := f.ByteOrder.Uint32(load)
++			switch macho.LoadCmd(cmd) {
++			default:
++				errorf("unexpected macho load cmd %s", macho.LoadCmd(cmd))
++			case macho.LoadCmdUnixThread:
++				data := make([]uint32, len(load[8:])/4)
++				binary.Read(bytes.NewReader(load[8:]), f.ByteOrder, data)
++				if len(data) != 44 {
++					errorf("macho thread len(data) = %d, want 42", len(data))
++					continue
++				}
++				if data[0] != 4 {
++					errorf("macho thread type = %d, want 4", data[0])
++				}
++				if data[1] != uint32(len(data))-2 {
++					errorf("macho thread desc len = %d, want %d", data[1], uint32(len(data))-2)
++					continue
++				}
++				for i, val := range data[2:] {
++					switch i {
++					default:
++						if val != 0 {
++							errorf("macho thread data[%d] = %#x, want 0", i, val)
++						}
++					case 32:
++						prog.Entry = Addr(val)
++					case 33:
++						prog.Entry |= Addr(val) << 32
++					}
++				}
++			}
++
++		case *macho.Segment:
++			if load.Addr < limit {
++				errorf("segments out of order: %q at %#x after %#x", load.Name, load.Addr, limit)
++			}
++			limit = load.Addr + load.Memsz
++			if load.Name == "__PAGEZERO" || load.Addr == 0 && load.Filesz == 0 {
++				if load.Name != "__PAGEZERO" {
++					errorf("segment with Addr=0, Filesz=0 is named %q, want %q", load.Name, "__PAGEZERO")
++				} else if load.Addr != 0 || load.Filesz != 0 {
++					errorf("segment %q has Addr=%#x, Filesz=%d, want Addr=%#x, Filesz=%d", load.Name, load.Addr, load.Filesz, 0, 0)
++				}
++				prog.UnmappedSize = Addr(load.Memsz)
++				continue
++			}
++
++			if !strings.HasPrefix(load.Name, "__") {
++				errorf("segment name %q does not begin with %q", load.Name, "__")
++			}
++			if strings.ToUpper(load.Name) != load.Name {
++				errorf("segment name %q is not all upper case", load.Name)
++			}
++
++			seg := &Segment{
++				Name:       strings.ToLower(strings.TrimPrefix(load.Name, "__")),
++				VirtAddr:   Addr(load.Addr),
++				VirtSize:   Addr(load.Memsz),
++				FileOffset: Addr(load.Offset),
++				FileSize:   Addr(load.Filesz),
++			}
++			prog.Segments = append(prog.Segments, seg)
++
++			data, err := load.Data()
++			if err != nil {
++				errorf("loading data from %q: %v", load.Name, err)
++			}
++			seg.Data = data
++
++			var maxprot, prot uint32
++			if load.Name == "__TEXT" {
++				maxprot, prot = 7, 5
++			} else {
++				maxprot, prot = 3, 3
++			}
++			if load.Maxprot != maxprot || load.Prot != prot {
++				errorf("segment %q protection is %d, %d, want %d, %d",
++					load.Name, load.Maxprot, load.Prot, maxprot, prot)
++			}
++
++			for len(msects) > 0 && msects[0].Addr < load.Addr+load.Memsz {
++				msect := msects[0]
++				msects = msects[1:]
++
++				if msect.Offset > 0 && prog.HeaderSize == 0 {
++					prog.HeaderSize = Addr(msect.Offset)
++					if seg.FileOffset != 0 {
++						errorf("initial segment %q does not map header", load.Name)
++					}
++					seg.VirtAddr += prog.HeaderSize
++					seg.VirtSize -= prog.HeaderSize
++					seg.FileOffset += prog.HeaderSize
++					seg.FileSize -= prog.HeaderSize
++					seg.Data = seg.Data[prog.HeaderSize:]
++				}
++
++				if msect.Addr < load.Addr {
++					errorf("section %q at address %#x is missing segment", msect.Name, msect.Addr)
++					continue
++				}
++
++				if !strings.HasPrefix(msect.Name, "__") {
++					errorf("section name %q does not begin with %q", msect.Name, "__")
++				}
++				if strings.ToLower(msect.Name) != msect.Name {
++					errorf("section name %q is not all lower case", msect.Name)
++				}
++				if msect.Seg != load.Name {
++					errorf("section %q is lists segment name %q, want %q",
++						msect.Name, msect.Seg, load.Name)
++				}
++				if uint64(msect.Offset) != uint64(load.Offset)+msect.Addr-load.Addr {
++					errorf("section %q file offset is %#x, want %#x",
++						msect.Name, msect.Offset, load.Offset+msect.Addr-load.Addr)
++				}
++				if msect.Reloff != 0 || msect.Nreloc != 0 {
++					errorf("section %q has reloff %d,%d, want %d,%d",
++						msect.Name, msect.Reloff, msect.Nreloc, 0, 0)
++				}
++				flags := uint32(0)
++				if msect.Name == "__text" {
++					flags = 0x400
++				}
++				if msect.Offset == 0 {
++					flags = 1
++				}
++				if msect.Flags != flags {
++					errorf("section %q flags = %#x, want %#x", msect.Name, msect.Flags, flags)
++				}
++				sect := &Section{
++					Name:     strings.ToLower(strings.TrimPrefix(msect.Name, "__")),
++					VirtAddr: Addr(msect.Addr),
++					Size:     Addr(msect.Size),
++					Align:    1 << msect.Align,
++				}
++				seg.Sections = append(seg.Sections, sect)
++			}
++		}
++	}
++
++	for _, msect := range msects {
++		errorf("section %q has no segment", msect.Name)
++	}
++
++	limit = 0
++	for _, msect := range f.Sections {
++		if msect.Addr < limit {
++			errorf("sections out of order: %q at %#x after %#x", msect.Name, msect.Addr, limit)
++		}
++		limit = msect.Addr + msect.Size
++	}
++
++	err = nil
++	if errors != nil {
++		err = fmt.Errorf("%s", strings.Join(errors, "\n\t"))
++	}
++	return prog, err
++}
+diff --git a/src/cmd/newlink/main.go b/src/cmd/newlink/main.go
+new file mode 100644
+index 0000000..b23f3f8
+--- /dev/null
++++ b/src/cmd/newlink/main.go
+@@ -0,0 +1,9 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Placeholder to keep build building.
++
++package main
++
++func main() {}
+diff --git a/src/cmd/newlink/pclntab.go b/src/cmd/newlink/pclntab.go
+new file mode 100644
+index 0000000..0a4cfc9
+--- /dev/null
++++ b/src/cmd/newlink/pclntab.go
+@@ -0,0 +1,480 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Generation of runtime function information (pclntab).
++
++package main
++
++import (
++	"cmd/internal/goobj"
++	"cmd/internal/obj"
++	"encoding/binary"
++	"os"
++	"sort"
++)
++
++var zerofunc goobj.Func
++
++// pclntab collects the runtime function data for each function that will
++// be listed in the binary and builds a single table describing all functions.
++// This table is used at run time for stack traces and to look up PC-specific
++// information during garbage collection. The symbol created is named
++// "pclntab" for historical reasons; the scope of the table has grown to
++// include more than just PC/line number correspondences.
++// The table format is documented at https://golang.org/s/go12symtab.
++func (p *Prog) pclntab() {
++	// Count number of functions going into the binary,
++	// so that we can size the initial index correctly.
++	nfunc := 0
++	for _, sym := range p.SymOrder {
++		if sym.Kind != goobj.STEXT {
++			continue
++		}
++		nfunc++
++	}
++
++	// Table header.
++	buf := new(SymBuffer)
++	buf.Init(p)
++	buf.SetSize(8 + p.ptrsize)
++	off := 0
++	off = buf.Uint32(off, 0xfffffffb)
++	off = buf.Uint8(off, 0)
++	off = buf.Uint8(off, 0)
++	off = buf.Uint8(off, uint8(p.pcquantum))
++	off = buf.Uint8(off, uint8(p.ptrsize))
++	off = buf.Uint(off, uint64(nfunc), p.ptrsize)
++	indexOff := off
++	off += (nfunc*2 + 1) * p.ptrsize // function index, to be filled in
++	off += 4                         // file table start offset, to be filled in
++	buf.SetSize(off)
++
++	// One-file cache for reading PCData tables from package files.
++	// TODO(rsc): Better I/O strategy.
++	var (
++		file  *os.File
++		fname string
++	)
++
++	// Files gives the file numbering for source file names recorded
++	// in the binary.
++	files := make(map[string]int)
++
++	// Build the table, build the index, and build the file name numbering.
++	// The loop here must visit functions in the same order that they will
++	// be stored in the binary, or else binary search over the index will fail.
++	// The runtime checks that the index is sorted properly at program start time.
++	var lastSym *Sym
++	for _, sym := range p.SymOrder {
++		if sym.Kind != goobj.STEXT {
++			continue
++		}
++		lastSym = sym
++
++		// Treat no recorded function information same as all zeros.
++		f := sym.Func
++		if f == nil {
++			f = &zerofunc
++		}
++
++		// Open package file if needed, for reading PC data.
++		if fname != sym.Package.File {
++			if file != nil {
++				file.Close()
++			}
++			var err error
++			file, err = os.Open(sym.Package.File)
++			if err != nil {
++				p.errorf("%v: %v", sym, err)
++				return
++			}
++			fname = sym.Package.File
++		}
++
++		// off is the offset of the table entry where we're going to write
++		// the encoded form of Func.
++		// indexOff is the current position in the table index;
++		// we add an entry in the index pointing at off.
++		off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
++		indexOff = buf.Addr(indexOff, sym.SymID, 0)
++		indexOff = buf.Uint(indexOff, uint64(off), p.ptrsize)
++
++		// The Func encoding starts with a header giving offsets
++		// to data blobs, and then the data blobs themselves.
++		// end gives the current write position for the data blobs.
++		end := off + p.ptrsize + 3*4 + 5*4 + len(f.PCData)*4 + len(f.FuncData)*p.ptrsize
++		if len(f.FuncData) > 0 {
++			end += -end & (p.ptrsize - 1)
++		}
++		buf.SetSize(end)
++
++		// entry uintptr
++		// name int32
++		// args int32
++		// frame int32
++		//
++		// The frame recorded in the object file is
++		// the frame size used in an assembly listing, which does
++		// not include the caller PC on the stack.
++		// The frame size we want to list here is the delta from
++		// this function's SP to its caller's SP, which does include
++		// the caller PC. Add p.ptrsize to f.Frame to adjust.
++		// TODO(rsc): Record the same frame size in the object file.
++		off = buf.Addr(off, sym.SymID, 0)
++		off = buf.Uint32(off, uint32(addString(buf, sym.Name)))
++		off = buf.Uint32(off, uint32(f.Args))
++		off = buf.Uint32(off, uint32(f.Frame+p.ptrsize))
++
++		// pcdata
++		off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCSP)))
++		off = buf.Uint32(off, uint32(addPCFileTable(p, buf, file, f.PCFile, sym, files)))
++		off = buf.Uint32(off, uint32(addPCTable(p, buf, file, f.PCLine)))
++		off = buf.Uint32(off, uint32(len(f.PCData)))
++		off = buf.Uint32(off, uint32(len(f.FuncData)))
++		for _, pcdata := range f.PCData {
++			off = buf.Uint32(off, uint32(addPCTable(p, buf, file, pcdata)))
++		}
++
++		// funcdata
++		if len(f.FuncData) > 0 {
++			off += -off & (p.ptrsize - 1) // must be pointer-aligned
++			for _, funcdata := range f.FuncData {
++				if funcdata.Sym.Name == "" {
++					off = buf.Uint(off, uint64(funcdata.Offset), p.ptrsize)
++				} else {
++					off = buf.Addr(off, funcdata.Sym, funcdata.Offset)
++				}
++			}
++		}
++
++		if off != end {
++			p.errorf("internal error: invalid math in pclntab: off=%#x end=%#x", off, end)
++			break
++		}
++	}
++	if file != nil {
++		file.Close()
++	}
++
++	// Final entry of index is end PC of last function.
++	indexOff = buf.Addr(indexOff, lastSym.SymID, int64(lastSym.Size))
++
++	// Start file table.
++	// Function index is immediately followed by offset to file table.
++	off = (buf.Size() + p.ptrsize - 1) &^ (p.ptrsize - 1)
++	buf.Uint32(indexOff, uint32(off))
++
++	// File table is an array of uint32s.
++	// The first entry gives 1+n, the size of the array.
++	// The following n entries hold offsets to string data.
++	// File number n uses the string pointed at by entry n.
++	// File number 0 is invalid.
++	buf.SetSize(off + (1+len(files))*4)
++	buf.Uint32(off, uint32(1+len(files)))
++	var filestr []string
++	for file := range files {
++		filestr = append(filestr, file)
++	}
++	sort.Strings(filestr)
++	for _, file := range filestr {
++		id := files[file]
++		buf.Uint32(off+4*id, uint32(addString(buf, file)))
++	}
++
++	pclntab := &Sym{
++		Sym: &goobj.Sym{
++			SymID: goobj.SymID{Name: "runtime.pclntab"},
++			Kind:  goobj.SPCLNTAB,
++			Size:  buf.Size(),
++			Reloc: buf.Reloc(),
++		},
++		Bytes: buf.Bytes(),
++	}
++	p.addSym(pclntab)
++}
++
++// addString appends the string s to the buffer b.
++// It returns the offset of the beginning of the string in the buffer.
++func addString(b *SymBuffer, s string) int {
++	off := b.Size()
++	b.SetSize(off + len(s) + 1)
++	copy(b.data[off:], s)
++	return off
++}
++
++// addPCTable appends the PC-data table stored in the file f at the location loc
++// to the symbol buffer b. It returns the offset of the beginning of the table
++// in the buffer.
++func addPCTable(p *Prog, b *SymBuffer, f *os.File, loc goobj.Data) int {
++	if loc.Size == 0 {
++		return 0
++	}
++	off := b.Size()
++	b.SetSize(off + int(loc.Size))
++	_, err := f.ReadAt(b.data[off:off+int(loc.Size)], loc.Offset)
++	if err != nil {
++		p.errorf("%v", err)
++	}
++	return off
++}
++
++// addPCFileTable is like addPCTable, but it renumbers the file names referred to by the table
++// to use the global numbering maintained in the files map. It adds new files to the
++// map as necessary.
++func addPCFileTable(p *Prog, b *SymBuffer, f *os.File, loc goobj.Data, sym *Sym, files map[string]int) int {
++	if loc.Size == 0 {
++		return 0
++	}
++	off := b.Size()
++
++	src := make([]byte, loc.Size)
++	_, err := f.ReadAt(src, loc.Offset)
++	if err != nil {
++		p.errorf("%v", err)
++		return 0
++	}
++
++	filenum := make([]int, len(sym.Func.File))
++	for i, name := range sym.Func.File {
++		num := files[name]
++		if num == 0 {
++			num = len(files) + 1
++			files[name] = num
++		}
++		filenum[i] = num
++	}
++
++	var dst []byte
++	newval := int32(-1)
++	var it PCIter
++	for it.Init(p, src); !it.Done; it.Next() {
++		// value delta
++		oldval := it.Value
++		val := oldval
++		if oldval != -1 {
++			if oldval < 0 || int(oldval) >= len(filenum) {
++				p.errorf("%s: corrupt pc-file table", sym)
++				break
++			}
++			val = int32(filenum[oldval])
++		}
++		dv := val - newval
++		newval = val
++		uv := uint32(dv<<1) ^ uint32(dv>>31)
++		dst = appendVarint(dst, uv)
++
++		// pc delta
++		dst = appendVarint(dst, it.NextPC-it.PC)
++	}
++	if it.Corrupt {
++		p.errorf("%s: corrupt pc-file table", sym)
++	}
++
++	// terminating value delta
++	dst = appendVarint(dst, 0)
++
++	b.SetSize(off + len(dst))
++	copy(b.data[off:], dst)
++	return off
++}
++
++// A SymBuffer is a buffer for preparing the data image of a
++// linker-generated symbol.
++type SymBuffer struct {
++	data    []byte
++	reloc   []goobj.Reloc
++	order   binary.ByteOrder
++	ptrsize int
++}
++
++// Init initializes the buffer for writing.
++func (b *SymBuffer) Init(p *Prog) {
++	b.data = nil
++	b.reloc = nil
++	b.order = p.byteorder
++	b.ptrsize = p.ptrsize
++}
++
++// Bytes returns the buffer data.
++func (b *SymBuffer) Bytes() []byte {
++	return b.data
++}
++
++// SetSize sets the buffer's data size to n bytes.
++func (b *SymBuffer) SetSize(n int) {
++	for cap(b.data) < n {
++		b.data = append(b.data[:cap(b.data)], 0)
++	}
++	b.data = b.data[:n]
++}
++
++// Size returns the buffer's data size.
++func (b *SymBuffer) Size() int {
++	return len(b.data)
++}
++
++// Reloc returns the buffered relocations.
++func (b *SymBuffer) Reloc() []goobj.Reloc {
++	return b.reloc
++}
++
++// Uint8 sets the uint8 at offset off to v.
++// It returns the offset just beyond v.
++func (b *SymBuffer) Uint8(off int, v uint8) int {
++	b.data[off] = v
++	return off + 1
++}
++
++// Uint16 sets the uint16 at offset off to v.
++// It returns the offset just beyond v.
++func (b *SymBuffer) Uint16(off int, v uint16) int {
++	b.order.PutUint16(b.data[off:], v)
++	return off + 2
++}
++
++// Uint32 sets the uint32 at offset off to v.
++// It returns the offset just beyond v.
++func (b *SymBuffer) Uint32(off int, v uint32) int {
++	b.order.PutUint32(b.data[off:], v)
++	return off + 4
++}
++
++// Uint64 sets the uint64 at offset off to v.
++// It returns the offset just beyond v.
++func (b *SymBuffer) Uint64(off int, v uint64) int {
++	b.order.PutUint64(b.data[off:], v)
++	return off + 8
++}
++
++// Uint sets the size-byte unsigned integer at offset off to v.
++// It returns the offset just beyond v.
++func (b *SymBuffer) Uint(off int, v uint64, size int) int {
++	switch size {
++	case 1:
++		return b.Uint8(off, uint8(v))
++	case 2:
++		return b.Uint16(off, uint16(v))
++	case 4:
++		return b.Uint32(off, uint32(v))
++	case 8:
++		return b.Uint64(off, v)
++	}
++	panic("invalid use of SymBuffer.SetUint")
++}
++
++// Addr sets the pointer-sized address at offset off to refer
++// to symoff bytes past the start of sym. It returns the offset
++// just beyond the address.
++func (b *SymBuffer) Addr(off int, sym goobj.SymID, symoff int64) int {
++	b.reloc = append(b.reloc, goobj.Reloc{
++		Offset: off,
++		Size:   b.ptrsize,
++		Sym:    sym,
++		Add:    int(symoff),
++		Type:   obj.R_ADDR,
++	})
++	return off + b.ptrsize
++}
++
++// A PCIter implements iteration over PC-data tables.
++//
++//	var it PCIter
++//	for it.Init(p, data); !it.Done; it.Next() {
++//		it.Value holds from it.PC up to (but not including) it.NextPC
++//	}
++//	if it.Corrupt {
++//		data was malformed
++//	}
++//
++type PCIter struct {
++	PC        uint32
++	NextPC    uint32
++	Value     int32
++	Done      bool
++	Corrupt   bool
++	p         []byte
++	start     bool
++	pcquantum uint32
++}
++
++// Init initializes the iteration.
++// On return, if it.Done is true, the iteration is over.
++// Otherwise it.Value applies in the pc range [it.PC, it.NextPC).
++func (it *PCIter) Init(p *Prog, buf []byte) {
++	it.p = buf
++	it.PC = 0
++	it.NextPC = 0
++	it.Value = -1
++	it.start = true
++	it.pcquantum = uint32(p.pcquantum)
++	it.Done = false
++	it.Next()
++}
++
++// Next steps forward one entry in the table.
++// On return, if it.Done is true, the iteration is over.
++// Otherwise it.Value applies in the pc range [it.PC, it.NextPC).
++func (it *PCIter) Next() {
++	it.PC = it.NextPC
++	if it.Done {
++		return
++	}
++	if len(it.p) == 0 {
++		it.Done = true
++		return
++	}
++
++	// value delta
++	uv, p, ok := decodeVarint(it.p)
++	if !ok {
++		it.Done = true
++		it.Corrupt = true
++		return
++	}
++	it.p = p
++	if uv == 0 && !it.start {
++		it.Done = true
++		return
++	}
++	it.start = false
++	sv := int32(uv>>1) ^ int32(uv<<31)>>31
++	it.Value += sv
++
++	// pc delta
++	uv, it.p, ok = decodeVarint(it.p)
++	if !ok {
++		it.Done = true
++		it.Corrupt = true
++		return
++	}
++	it.NextPC = it.PC + uv*it.pcquantum
++}
++
++// decodeVarint decodes an unsigned varint from p,
++// reporting the value, the remainder of the data, and
++// whether the decoding was successful.
++func decodeVarint(p []byte) (v uint32, rest []byte, ok bool) {
++	for shift := uint(0); ; shift += 7 {
++		if len(p) == 0 {
++			return
++		}
++		c := uint32(p[0])
++		p = p[1:]
++		v |= (c & 0x7F) << shift
++		if c&0x80 == 0 {
++			break
++		}
++	}
++	return v, p, true
++}
++
++// appendVarint appends an unsigned varint encoding of v to p
++// and returns the resulting slice.
++func appendVarint(p []byte, v uint32) []byte {
++	for ; v >= 0x80; v >>= 7 {
++		p = append(p, byte(v)|0x80)
++	}
++	p = append(p, byte(v))
++	return p
++}
+diff --git a/src/cmd/newlink/pclntab_test.go b/src/cmd/newlink/pclntab_test.go
+new file mode 100644
+index 0000000..ea80806
+--- /dev/null
++++ b/src/cmd/newlink/pclntab_test.go
+@@ -0,0 +1,340 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"bytes"
++	"cmd/internal/goobj"
++	"fmt"
++	"math/rand"
++	"sort"
++	"strings"
++	"testing"
++)
++
++// Test of pcln table encoding.
++// testdata/genpcln.go generates an assembly file with
++// pseudorandom values for the data that pclntab stores.
++// This test recomputes the same pseudorandom stream
++// and checks that the final linked binary uses those values
++// as well.
++func TestPclntab(t *testing.T) {
++	p := &Prog{
++		GOOS:        "darwin",
++		GOARCH:      "amd64",
++		Error:       func(s string) { t.Error(s) },
++		StartSym:    "start",
++		omitRuntime: true,
++	}
++	var buf bytes.Buffer
++	p.link(&buf, "testdata/pclntab.6")
++	if p.NumError > 0 {
++		return
++	}
++
++	// The algorithm for computing values here must match
++	// the one in testdata/genpcln.go.
++	for f := 0; f < 3; f++ {
++		file := "input"
++		line := 1
++		rnd := rand.New(rand.NewSource(int64(f)))
++		args := rnd.Intn(100) * 8
++		frame := 32 + rnd.Intn(32)/8*8
++		size := 200 + rnd.Intn(100)*8
++
++		name := fmt.Sprintf("func%d", f)
++		r, off, fargs, fframe, ok := findFunc(t, p, name)
++		if !ok {
++			continue // error already printed
++		}
++		if fargs != args {
++			t.Errorf("%s: args=%d, want %d", name, fargs, args)
++		}
++		if fframe != frame+8 {
++			t.Errorf("%s: frame=%d, want %d", name, fframe, frame+8)
++		}
++
++		// Check FUNCDATA 1.
++		fdata, ok := loadFuncdata(t, r, name, off, 1)
++		if ok {
++			fsym := p.Syms[goobj.SymID{Name: fmt.Sprintf("funcdata%d", f)}]
++			if fsym == nil {
++				t.Errorf("funcdata%d is missing in binary", f)
++			} else if fdata != fsym.Addr {
++				t.Errorf("%s: funcdata 1 = %#x, want %#x", name, fdata, fsym.Addr)
++			}
++		}
++
++		// Walk code checking pcdata values.
++		spadj := 0
++		pcdata1 := -1
++		pcdata2 := -1
++
++		checkPCSP(t, r, name, off, 0, 0)
++		checkPCData(t, r, name, off, 0, 0, -1)
++		checkPCData(t, r, name, off, 0, 1, -1)
++		checkPCData(t, r, name, off, 0, 2, -1)
++
++		firstpc := 4
++		for i := 0; i < size; i++ {
++			pc := firstpc + i // skip SP adjustment to allocate frame
++			if i >= 0x100 && t.Failed() {
++				break
++			}
++			// Possible SP adjustment.
++			checkPCSP(t, r, name, off, pc, frame+spadj)
++			if rnd.Intn(100) == 0 {
++				checkPCFileLine(t, r, name, off, pc, file, line)
++				checkPCData(t, r, name, off, pc, 1, pcdata1)
++				checkPCData(t, r, name, off, pc, 2, pcdata2)
++				i += 1
++				pc = firstpc + i
++				checkPCFileLine(t, r, name, off, pc-1, file, line)
++				checkPCData(t, r, name, off, pc-1, 1, pcdata1)
++				checkPCData(t, r, name, off, pc-1, 2, pcdata2)
++				checkPCSP(t, r, name, off, pc-1, frame+spadj)
++
++				if spadj <= -32 || spadj < 32 && rnd.Intn(2) == 0 {
++					spadj += 8
++				} else {
++					spadj -= 8
++				}
++				checkPCSP(t, r, name, off, pc, frame+spadj)
++			}
++
++			// Possible PCFile change.
++			if rnd.Intn(100) == 0 {
++				file = fmt.Sprintf("file%d.s", rnd.Intn(10))
++				line = rnd.Intn(100) + 1
++			}
++
++			// Possible PCLine change.
++			if rnd.Intn(10) == 0 {
++				line = rnd.Intn(1000) + 1
++			}
++
++			// Possible PCData $1 change.
++			if rnd.Intn(100) == 0 {
++				pcdata1 = rnd.Intn(1000)
++			}
++
++			// Possible PCData $2 change.
++			if rnd.Intn(100) == 0 {
++				pcdata2 = rnd.Intn(1000)
++			}
++
++			if i == 0 {
++				checkPCFileLine(t, r, name, off, 0, file, line)
++				checkPCFileLine(t, r, name, off, pc-1, file, line)
++			}
++			checkPCFileLine(t, r, name, off, pc, file, line)
++			checkPCData(t, r, name, off, pc, 1, pcdata1)
++			checkPCData(t, r, name, off, pc, 2, pcdata2)
++		}
++	}
++}
++
++// findFunc finds the function information in the pclntab of p
++// for the function with the given name.
++// It returns a symbol reader for pclntab, the offset of the function information
++// within that symbol, and the args and frame values read out of the information.
++func findFunc(t *testing.T, p *Prog, name string) (r *SymReader, off, args, frame int, ok bool) {
++	tabsym := p.Syms[goobj.SymID{Name: "runtime.pclntab"}]
++	if tabsym == nil {
++		t.Errorf("pclntab is missing in binary")
++		return
++	}
++
++	r = new(SymReader)
++	r.Init(p, tabsym)
++
++	// pclntab must with 8-byte header
++	if r.Uint32(0) != 0xfffffffb || r.Uint8(4) != 0 || r.Uint8(5) != 0 || r.Uint8(6) != uint8(p.pcquantum) || r.Uint8(7) != uint8(p.ptrsize) {
++		t.Errorf("pclntab has incorrect header %.8x", r.data[:8])
++		return
++	}
++
++	sym := p.Syms[goobj.SymID{Name: name}]
++	if sym == nil {
++		t.Errorf("%s is missing in the binary", name)
++		return
++	}
++
++	// index is nfunc addr0 off0 addr1 off1 ... addr_nfunc (sentinel)
++	nfunc := int(r.Addr(8))
++	i := sort.Search(nfunc, func(i int) bool {
++		return r.Addr(8+p.ptrsize*(1+2*i)) >= sym.Addr
++	})
++	if entry := r.Addr(8 + p.ptrsize*(1+2*i)); entry != sym.Addr {
++		indexTab := make([]Addr, 2*nfunc+1)
++		for j := range indexTab {
++			indexTab[j] = r.Addr(8 + p.ptrsize*(1+j))
++		}
++		t.Errorf("pclntab is missing entry for %s (%#x): %#x", name, sym.Addr, indexTab)
++		return
++	}
++
++	off = int(r.Addr(8 + p.ptrsize*(1+2*i+1)))
++
++	// func description at off is
++	//	entry addr
++	//	nameoff uint32
++	//	args uint32
++	//	frame uint32
++	//	pcspoff uint32
++	//	pcfileoff uint32
++	//	pclineoff uint32
++	//	npcdata uint32
++	//	nfuncdata uint32
++	//	pcdata npcdata*uint32
++	//	funcdata nfuncdata*addr
++	//
++	if entry := r.Addr(off); entry != sym.Addr {
++		t.Errorf("pclntab inconsistent: entry for %s addr=%#x has entry=%#x", name, sym.Addr, entry)
++		return
++	}
++	nameoff := int(r.Uint32(off + p.ptrsize))
++	args = int(r.Uint32(off + p.ptrsize + 1*4))
++	frame = int(r.Uint32(off + p.ptrsize + 2*4))
++
++	fname := r.String(nameoff)
++	if fname != name {
++		t.Errorf("pclntab inconsistent: entry for %s addr=%#x has name %q", name, sym.Addr, fname)
++	}
++
++	ok = true // off, args, frame are usable
++	return
++}
++
++// loadFuncdata returns the funcdata #fnum value
++// loaded from the function information for name.
++func loadFuncdata(t *testing.T, r *SymReader, name string, off int, fnum int) (Addr, bool) {
++	npcdata := int(r.Uint32(off + r.p.ptrsize + 6*4))
++	nfuncdata := int(r.Uint32(off + r.p.ptrsize + 7*4))
++	if fnum >= nfuncdata {
++		t.Errorf("pclntab(%s): no funcdata %d (only < %d)", name, fnum, nfuncdata)
++		return 0, false
++	}
++	fdataoff := off + r.p.ptrsize + (8+npcdata)*4 + fnum*r.p.ptrsize
++	fdataoff += fdataoff & 4
++	return r.Addr(fdataoff), true
++}
++
++// checkPCSP checks that the PCSP table in the function information at off
++// lists spadj as the sp delta for pc.
++func checkPCSP(t *testing.T, r *SymReader, name string, off, pc, spadj int) {
++	pcoff := r.Uint32(off + r.p.ptrsize + 3*4)
++	pcval, ok := readPCData(t, r, name, "PCSP", pcoff, pc)
++	if !ok {
++		return
++	}
++	if pcval != spadj {
++		t.Errorf("pclntab(%s): at pc=+%#x, pcsp=%d, want %d", name, pc, pcval, spadj)
++	}
++}
++
++// checkPCSP checks that the PCFile and PCLine tables in the function information at off
++// list file, line as the file name and line number for pc.
++func checkPCFileLine(t *testing.T, r *SymReader, name string, off, pc int, file string, line int) {
++	pcfileoff := r.Uint32(off + r.p.ptrsize + 4*4)
++	pclineoff := r.Uint32(off + r.p.ptrsize + 5*4)
++	pcfilenum, ok1 := readPCData(t, r, name, "PCFile", pcfileoff, pc)
++	pcline, ok2 := readPCData(t, r, name, "PCLine", pclineoff, pc)
++	if !ok1 || !ok2 {
++		return
++	}
++	nfunc := int(r.Addr(8))
++	filetaboff := r.Uint32(8 + r.p.ptrsize*2*(nfunc+1))
++	nfile := int(r.Uint32(int(filetaboff)))
++	if pcfilenum <= 0 || pcfilenum >= nfile {
++		t.Errorf("pclntab(%s): at pc=+%#x, filenum=%d (invalid; nfile=%d)", name, pc, pcfilenum, nfile)
++	}
++	pcfile := r.String(int(r.Uint32(int(filetaboff) + pcfilenum*4)))
++	if !strings.HasSuffix(pcfile, file) {
++		t.Errorf("pclntab(%s): at pc=+%#x, file=%q, want %q", name, pc, pcfile, file)
++	}
++	if pcline != line {
++		t.Errorf("pclntab(%s): at pc=+%#x, line=%d, want %d", name, pc, pcline, line)
++	}
++}
++
++// checkPCData checks that the PCData#pnum table in the function information at off
++// list val as the value for pc.
++func checkPCData(t *testing.T, r *SymReader, name string, off, pc, pnum, val int) {
++	pcoff := r.Uint32(off + r.p.ptrsize + (8+pnum)*4)
++	pcval, ok := readPCData(t, r, name, fmt.Sprintf("PCData#%d", pnum), pcoff, pc)
++	if !ok {
++		return
++	}
++	if pcval != val {
++		t.Errorf("pclntab(%s): at pc=+%#x, pcdata#%d=%d, want %d", name, pc, pnum, pcval, val)
++	}
++}
++
++// readPCData reads the PCData table offset off
++// to obtain and return the value associated with pc.
++func readPCData(t *testing.T, r *SymReader, name, pcdataname string, pcoff uint32, pc int) (int, bool) {
++	// "If pcsp, pcfile, pcln, or any of the pcdata offsets is zero,
++	// that table is considered missing, and all PCs take value -1."
++	if pcoff == 0 {
++		return -1, true
++	}
++
++	var it PCIter
++	for it.Init(r.p, r.data[pcoff:]); !it.Done; it.Next() {
++		if it.PC <= uint32(pc) && uint32(pc) < it.NextPC {
++			return int(it.Value), true
++		}
++	}
++	if it.Corrupt {
++		t.Errorf("pclntab(%s): %s: corrupt pcdata table", name, pcdataname)
++	}
++	return 0, false
++}
++
++// A SymReader provides typed access to the data for a symbol.
++type SymReader struct {
++	p    *Prog
++	data []byte
++}
++
++func (r *SymReader) Init(p *Prog, sym *Sym) {
++	seg := sym.Section.Segment
++	off := sym.Addr - seg.VirtAddr
++	data := seg.Data[off : off+Addr(sym.Size)]
++	r.p = p
++	r.data = data
++}
++
++func (r *SymReader) Uint8(off int) uint8 {
++	return r.data[off]
++}
++
++func (r *SymReader) Uint16(off int) uint16 {
++	return r.p.byteorder.Uint16(r.data[off:])
++}
++
++func (r *SymReader) Uint32(off int) uint32 {
++	return r.p.byteorder.Uint32(r.data[off:])
++}
++
++func (r *SymReader) Uint64(off int) uint64 {
++	return r.p.byteorder.Uint64(r.data[off:])
++}
++
++func (r *SymReader) Addr(off int) Addr {
++	if r.p.ptrsize == 4 {
++		return Addr(r.Uint32(off))
++	}
++	return Addr(r.Uint64(off))
++}
++
++func (r *SymReader) String(off int) string {
++	end := off
++	for r.data[end] != '\x00' {
++		end++
++	}
++	return string(r.data[off:end])
++}
+diff --git a/src/cmd/newlink/prog.go b/src/cmd/newlink/prog.go
+new file mode 100644
+index 0000000..77fb1ec
+--- /dev/null
++++ b/src/cmd/newlink/prog.go
+@@ -0,0 +1,220 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"cmd/internal/goobj"
++	"encoding/binary"
++	"fmt"
++	"go/build"
++	"io"
++	"os"
++	"runtime"
++)
++
++// A Prog holds state for constructing an executable (program) image.
++//
++// The usual sequence of operations on a Prog is:
++//
++//	p.init()
++//	p.scan(file)
++//	p.dead()
++//	p.runtime()
++//	p.layout()
++//	p.load()
++//	p.debug()
++//	p.write(w)
++//
++// p.init is in this file. The rest of the methods are in files
++// named for the method. The convenience method p.link runs
++// this sequence.
++//
++type Prog struct {
++	// Context
++	GOOS     string       // target operating system
++	GOARCH   string       // target architecture
++	Format   string       // desired file format ("elf", "macho", ...)
++	Error    func(string) // called to report an error (if set)
++	NumError int          // number of errors printed
++	StartSym string
++
++	// Derived context
++	arch
++	formatter   formatter
++	startSym    goobj.SymID
++	pkgdir      string
++	omitRuntime bool // do not load runtime package
++
++	// Input
++	Packages   map[string]*Package  // loaded packages, by import path
++	Syms       map[goobj.SymID]*Sym // defined symbols, by symbol ID
++	Missing    map[goobj.SymID]bool // missing symbols
++	Dead       map[goobj.SymID]bool // symbols removed as dead
++	SymOrder   []*Sym               // order syms were scanned
++	MaxVersion int                  // max SymID.Version, for generating fresh symbol IDs
++
++	// Output
++	UnmappedSize Addr       // size of unmapped region at address 0
++	HeaderSize   Addr       // size of object file header
++	Entry        Addr       // virtual address where execution begins
++	Segments     []*Segment // loaded memory segments
++}
++
++// An arch describes architecture-dependent settings.
++type arch struct {
++	byteorder binary.ByteOrder
++	ptrsize   int
++	pcquantum int
++}
++
++// A formatter takes care of the details of generating a particular
++// kind of executable file.
++type formatter interface {
++	// headerSize returns the footprint of the header for p
++	// in both virtual address space and file bytes.
++	// The footprint does not include any bytes stored at the
++	// end of the file.
++	headerSize(p *Prog) (virt, file Addr)
++
++	// write writes the executable file for p to w.
++	write(w io.Writer, p *Prog)
++}
++
++// An Addr represents a virtual memory address, a file address, or a size.
++// It must be a uint64, not a uintptr, so that a 32-bit linker can still generate a 64-bit binary.
++// It must be unsigned in order to link programs placed at very large start addresses.
++// Math involving Addrs must be checked carefully not to require negative numbers.
++type Addr uint64
++
++// A Package is a Go package loaded from a file.
++type Package struct {
++	*goobj.Package        // table of contents
++	File           string // file name for reopening
++	Syms           []*Sym // symbols defined by this package
++}
++
++// A Sym is a symbol defined in a loaded package.
++type Sym struct {
++	*goobj.Sym          // symbol metadata from package file
++	Package    *Package // package defining symbol
++	Section    *Section // section where symbol is placed in output program
++	Addr       Addr     // virtual address of symbol in output program
++	Bytes      []byte   // symbol data, for internally defined symbols
++}
++
++// A Segment is a loaded memory segment.
++// A Prog is expected to have segments named "text" and optionally "data",
++// in that order, before any other segments.
++type Segment struct {
++	Name       string     // name of segment: "text", "data", ...
++	VirtAddr   Addr       // virtual memory address of segment base
++	VirtSize   Addr       // size of segment in memory
++	FileOffset Addr       // file offset of segment base
++	FileSize   Addr       // size of segment in file; can be less than VirtSize
++	Sections   []*Section // sections inside segment
++	Data       []byte     // raw data of segment image
++}
++
++// A Section is part of a loaded memory segment.
++type Section struct {
++	Name     string   // name of section: "text", "rodata", "noptrbss", and so on
++	VirtAddr Addr     // virtual memory address of section base
++	Size     Addr     // size of section in memory
++	Align    Addr     // required alignment
++	InFile   bool     // section has image data in file (like data, unlike bss)
++	Syms     []*Sym   // symbols stored in section
++	Segment  *Segment // segment containing section
++}
++
++func (p *Prog) errorf(format string, args ...interface{}) {
++	if p.Error != nil {
++		p.Error(fmt.Sprintf(format, args...))
++	} else {
++		fmt.Fprintf(os.Stderr, format+"\n", args...)
++	}
++	p.NumError++
++}
++
++// link is the one-stop convenience method for running a link.
++// It writes to w the object file generated from using mainFile as the main package.
++func (p *Prog) link(w io.Writer, mainFile string) {
++	p.init()
++	p.scan(mainFile)
++	if p.NumError > 0 {
++		return
++	}
++	p.dead()
++	p.runtime()
++	p.autoData()
++	p.layout()
++	p.autoConst()
++	if p.NumError > 0 {
++		return
++	}
++	p.load()
++	if p.NumError > 0 {
++		return
++	}
++	p.debug()
++	if p.NumError > 0 {
++		return
++	}
++	p.write(w)
++}
++
++// init initializes p for use by the other methods.
++func (p *Prog) init() {
++	// Set default context if not overridden.
++	if p.GOOS == "" {
++		p.GOOS = build.Default.GOOS
++	}
++	if p.GOARCH == "" {
++		p.GOARCH = build.Default.GOARCH
++	}
++	if p.Format == "" {
++		p.Format = goosFormat[p.GOOS]
++		if p.Format == "" {
++			p.errorf("no default file format for GOOS %q", p.GOOS)
++			return
++		}
++	}
++	if p.StartSym == "" {
++		p.StartSym = fmt.Sprintf("_rt0_%s_%s", p.GOARCH, p.GOOS)
++	}
++
++	// Derive internal context.
++	p.formatter = formatters[p.Format]
++	if p.formatter == nil {
++		p.errorf("unknown output file format %q", p.Format)
++		return
++	}
++	p.startSym = goobj.SymID{Name: p.StartSym}
++	arch, ok := arches[p.GOARCH]
++	if !ok {
++		p.errorf("unknown GOOS %q", p.GOOS)
++		return
++	}
++	p.arch = arch
++
++	p.pkgdir = fmt.Sprintf("%s/pkg/%s_%s", runtime.GOROOT(), p.GOOS, p.GOARCH)
++}
++
++// goosFormat records the default format for each known GOOS value.
++var goosFormat = map[string]string{
++	"darwin": "darwin",
++}
++
++// formatters records the format implementation for each known format value.
++var formatters = map[string]formatter{
++	"darwin": machoFormat{},
++}
++
++var arches = map[string]arch{
++	"amd64": {
++		byteorder: binary.LittleEndian,
++		ptrsize:   8,
++		pcquantum: 1,
++	},
++}
+diff --git a/src/cmd/newlink/prog_test.go b/src/cmd/newlink/prog_test.go
+new file mode 100644
+index 0000000..0853506
+--- /dev/null
++++ b/src/cmd/newlink/prog_test.go
+@@ -0,0 +1,163 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++import (
++	"bytes"
++	"fmt"
++	"io/ioutil"
++	"testing"
++)
++
++// shiftProg adjusts the addresses in p.
++// It adds vdelta to all virtual addresses and fdelta to all file offsets.
++func shiftProg(p *Prog, vdelta Addr, fdelta Addr) {
++	p.Entry += vdelta
++	for _, seg := range p.Segments {
++		seg.FileOffset += fdelta
++		seg.VirtAddr += vdelta
++		for _, sect := range seg.Sections {
++			sect.VirtAddr += vdelta
++			for _, sym := range sect.Syms {
++				sym.Addr += vdelta
++			}
++		}
++	}
++}
++
++// diffProg returns a list of differences between p and q,
++// assuming p is being checked and q is the correct answer.
++func diffProg(p, q *Prog) []string {
++	var errors []string
++	if p.UnmappedSize != q.UnmappedSize {
++		errors = append(errors, fmt.Sprintf("p.UnmappedSize = %#x, want %#x", p.UnmappedSize, q.UnmappedSize))
++	}
++	if p.HeaderSize != q.HeaderSize {
++		errors = append(errors, fmt.Sprintf("p.HeaderSize = %#x, want %#x", p.HeaderSize, q.HeaderSize))
++	}
++	if p.Entry != q.Entry {
++		errors = append(errors, fmt.Sprintf("p.Entry = %#x, want %#x", p.Entry, q.Entry))
++	}
++	for i := 0; i < len(p.Segments) || i < len(q.Segments); i++ {
++		if i >= len(p.Segments) {
++			errors = append(errors, fmt.Sprintf("p missing segment %q", q.Segments[i].Name))
++			continue
++		}
++		if i >= len(q.Segments) {
++			errors = append(errors, fmt.Sprintf("p has extra segment %q", p.Segments[i].Name))
++			continue
++		}
++		pseg := p.Segments[i]
++		qseg := q.Segments[i]
++		if pseg.Name != qseg.Name {
++			errors = append(errors, fmt.Sprintf("segment %d Name = %q, want %q", i, pseg.Name, qseg.Name))
++			continue // probably out of sync
++		}
++		if pseg.VirtAddr != qseg.VirtAddr {
++			errors = append(errors, fmt.Sprintf("segment %q VirtAddr = %#x, want %#x", pseg.Name, pseg.VirtAddr, qseg.VirtAddr))
++		}
++		if pseg.VirtSize != qseg.VirtSize {
++			errors = append(errors, fmt.Sprintf("segment %q VirtSize = %#x, want %#x", pseg.Name, pseg.VirtSize, qseg.VirtSize))
++		}
++		if pseg.FileOffset != qseg.FileOffset {
++			errors = append(errors, fmt.Sprintf("segment %q FileOffset = %#x, want %#x", pseg.Name, pseg.FileOffset, qseg.FileOffset))
++		}
++		if pseg.FileSize != qseg.FileSize {
++			errors = append(errors, fmt.Sprintf("segment %q FileSize = %#x, want %#x", pseg.Name, pseg.FileSize, qseg.FileSize))
++		}
++		if len(pseg.Data) != len(qseg.Data) {
++			errors = append(errors, fmt.Sprintf("segment %q len(Data) = %d, want %d", pseg.Name, len(pseg.Data), len(qseg.Data)))
++		} else if !bytes.Equal(pseg.Data, qseg.Data) {
++			errors = append(errors, fmt.Sprintf("segment %q Data mismatch:\n\thave %x\n\twant %x", pseg.Name, pseg.Data, qseg.Data))
++		}
++
++		for j := 0; j < len(pseg.Sections) || j < len(qseg.Sections); j++ {
++			if j >= len(pseg.Sections) {
++				errors = append(errors, fmt.Sprintf("segment %q missing section %q", pseg.Name, qseg.Sections[i].Name))
++				continue
++			}
++			if j >= len(qseg.Sections) {
++				errors = append(errors, fmt.Sprintf("segment %q has extra section %q", pseg.Name, pseg.Sections[i].Name))
++				continue
++			}
++			psect := pseg.Sections[j]
++			qsect := qseg.Sections[j]
++			if psect.Name != qsect.Name {
++				errors = append(errors, fmt.Sprintf("segment %q, section %d Name = %q, want %q", pseg.Name, j, psect.Name, qsect.Name))
++				continue // probably out of sync
++			}
++
++			if psect.VirtAddr != qsect.VirtAddr {
++				errors = append(errors, fmt.Sprintf("segment %q section %q VirtAddr = %#x, want %#x", pseg.Name, psect.Name, psect.VirtAddr, qsect.VirtAddr))
++			}
++			if psect.Size != qsect.Size {
++				errors = append(errors, fmt.Sprintf("segment %q section %q Size = %#x, want %#x", pseg.Name, psect.Name, psect.Size, qsect.Size))
++			}
++			if psect.Align != qsect.Align {
++				errors = append(errors, fmt.Sprintf("segment %q section %q Align = %#x, want %#x", pseg.Name, psect.Name, psect.Align, qsect.Align))
++			}
++		}
++	}
++
++	return errors
++}
++
++// cloneProg returns a deep copy of p.
++func cloneProg(p *Prog) *Prog {
++	q := new(Prog)
++	*q = *p
++	q.Segments = make([]*Segment, len(p.Segments))
++	for i, seg := range p.Segments {
++		q.Segments[i] = cloneSegment(seg)
++	}
++	return q
++}
++
++// cloneSegment returns a deep copy of seg.
++func cloneSegment(seg *Segment) *Segment {
++	t := new(Segment)
++	*t = *seg
++	t.Sections = make([]*Section, len(seg.Sections))
++	for i, sect := range seg.Sections {
++		t.Sections[i] = cloneSection(sect)
++	}
++	t.Data = make([]byte, len(seg.Data))
++	copy(t.Data, seg.Data)
++	return t
++}
++
++// cloneSection returns a deep copy of section.
++func cloneSection(sect *Section) *Section {
++	// At the moment, there's nothing we need to make a deep copy of.
++	t := new(Section)
++	*t = *sect
++	return t
++}
++
++const saveMismatch = true
++
++// checkGolden checks that data matches the named file.
++// If not, it reports the error to the test.
++func checkGolden(t *testing.T, data []byte, name string) {
++	golden := mustParseHexdumpFile(t, name)
++	if !bytes.Equal(data, golden) {
++		if saveMismatch {
++			ioutil.WriteFile(name+".raw", data, 0666)
++			ioutil.WriteFile(name+".hex", []byte(hexdump(data)), 0666)
++		}
++		// TODO(rsc): A better diff would be nice, as needed.
++		i := 0
++		for i < len(data) && i < len(golden) && data[i] == golden[i] {
++			i++
++		}
++		if i >= len(data) {
++			t.Errorf("%s: output file shorter than expected: have %d bytes, want %d", name, len(data), len(golden))
++		} else if i >= len(golden) {
++			t.Errorf("%s: output file larger than expected: have %d bytes, want %d", name, len(data), len(golden))
++		} else {
++			t.Errorf("%s: output file differs at byte %d: have %#02x, want %#02x", name, i, data[i], golden[i])
++		}
++	}
++}
+diff --git a/src/cmd/newlink/runtime.go b/src/cmd/newlink/runtime.go
+new file mode 100644
+index 0000000..acda2d2
+--- /dev/null
++++ b/src/cmd/newlink/runtime.go
+@@ -0,0 +1,28 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Generation of runtime-accessible data structures.
++// See also debug.go.
++
++package main
++
++import "cmd/internal/goobj"
++
++func (p *Prog) runtime() {
++	p.pclntab()
++
++	// TODO: Implement garbage collection data.
++	p.addSym(&Sym{
++		Sym: &goobj.Sym{
++			SymID: goobj.SymID{Name: "runtime.gcdata"},
++			Kind:  goobj.SRODATA,
++		},
++	})
++	p.addSym(&Sym{
++		Sym: &goobj.Sym{
++			SymID: goobj.SymID{Name: "runtime.gcbss"},
++			Kind:  goobj.SRODATA,
++		},
++	})
++}
+diff --git a/src/cmd/newlink/scan.go b/src/cmd/newlink/scan.go
+new file mode 100644
+index 0000000..7feb0d8
+--- /dev/null
++++ b/src/cmd/newlink/scan.go
+@@ -0,0 +1,187 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Initial scan of packages making up a program.
++
++// TODO(rsc): Rename goobj.SymID.Version to StaticID to avoid confusion with the ELF meaning of version.
++// TODO(rsc): Fix file format so that SBSS/SNOPTRBSS with data is listed as SDATA/SNOPTRDATA.
++// TODO(rsc): Parallelize scan to overlap file i/o where possible.
++
++package main
++
++import (
++	"cmd/internal/goobj"
++	"os"
++	"sort"
++	"strings"
++)
++
++// scan scans all packages making up the program, starting with package main defined in mainfile.
++func (p *Prog) scan(mainfile string) {
++	p.initScan()
++	p.scanFile("main", mainfile)
++	if len(p.Missing) > 0 && !p.omitRuntime {
++		p.scanImport("runtime")
++	}
++
++	var missing []string
++	for sym := range p.Missing {
++		if !p.isAuto(sym) {
++			missing = append(missing, sym.String())
++		}
++	}
++
++	if missing != nil {
++		sort.Strings(missing)
++		for _, sym := range missing {
++			p.errorf("undefined: %s", sym)
++		}
++	}
++
++	// TODO(rsc): Walk import graph to diagnose cycles.
++}
++
++// initScan initializes the Prog fields needed by scan.
++func (p *Prog) initScan() {
++	p.Packages = make(map[string]*Package)
++	p.Syms = make(map[goobj.SymID]*Sym)
++	p.Missing = make(map[goobj.SymID]bool)
++	p.Missing[p.startSym] = true
++}
++
++// scanFile reads file to learn about the package with the given import path.
++func (p *Prog) scanFile(pkgpath string, file string) {
++	pkg := &Package{
++		File: file,
++	}
++	p.Packages[pkgpath] = pkg
++
++	f, err := os.Open(file)
++	if err != nil {
++		p.errorf("%v", err)
++		return
++	}
++	gp, err := goobj.Parse(f, pkgpath)
++	f.Close()
++	if err != nil {
++		p.errorf("reading %s: %v", file, err)
++		return
++	}
++
++	// TODO(rsc): Change cmd/internal/goobj to record package name as gp.Name.
++	// TODO(rsc): If pkgpath == "main", check that gp.Name == "main".
++
++	pkg.Package = gp
++
++	for _, gs := range gp.Syms {
++		// TODO(rsc): Fix file format instead of this workaround.
++		if gs.Data.Size > 0 {
++			switch gs.Kind {
++			case goobj.SBSS:
++				gs.Kind = goobj.SDATA
++			case goobj.SNOPTRBSS:
++				gs.Kind = goobj.SNOPTRDATA
++			}
++		}
++
++		if gs.Version != 0 {
++			gs.Version += p.MaxVersion
++		}
++		for i := range gs.Reloc {
++			r := &gs.Reloc[i]
++			if r.Sym.Version != 0 {
++				r.Sym.Version += p.MaxVersion
++			}
++			if p.Syms[r.Sym] == nil {
++				p.Missing[r.Sym] = true
++			}
++		}
++		if gs.Func != nil {
++			for i := range gs.Func.FuncData {
++				fdata := &gs.Func.FuncData[i]
++				if fdata.Sym.Name != "" {
++					if fdata.Sym.Version != 0 {
++						fdata.Sym.Version += p.MaxVersion
++					}
++					if p.Syms[fdata.Sym] == nil {
++						p.Missing[fdata.Sym] = true
++					}
++				}
++			}
++		}
++		if old := p.Syms[gs.SymID]; old != nil {
++			// Duplicate definition of symbol. Is it okay?
++			// TODO(rsc): Write test for this code.
++			switch {
++			// If both symbols are BSS (no data), take max of sizes
++			// but otherwise ignore second symbol.
++			case old.Data.Size == 0 && gs.Data.Size == 0:
++				if old.Size < gs.Size {
++					old.Size = gs.Size
++				}
++				continue
++
++			// If one is in BSS and one is not, use the one that is not.
++			case old.Data.Size > 0 && gs.Data.Size == 0:
++				continue
++			case gs.Data.Size > 0 && old.Data.Size == 0:
++				break // install gs as new symbol below
++
++			// If either is marked as DupOK, we can keep either one.
++			// Keep the one that we saw first.
++			case old.DupOK || gs.DupOK:
++				continue
++
++			// Otherwise, there's an actual conflict:
++			default:
++				p.errorf("symbol %s defined in both %s and %s %v %v", gs.SymID, old.Package.File, file, old.Data, gs.Data)
++				continue
++			}
++		}
++		s := &Sym{
++			Sym:     gs,
++			Package: pkg,
++		}
++		p.addSym(s)
++		delete(p.Missing, gs.SymID)
++
++		if s.Data.Size > int64(s.Size) {
++			p.errorf("%s: initialized data larger than symbol (%d > %d)", s, s.Data.Size, s.Size)
++		}
++	}
++	p.MaxVersion += pkg.MaxVersion
++
++	for i, pkgpath := range pkg.Imports {
++		// TODO(rsc): Fix file format to drop .a from recorded import path.
++		pkgpath = strings.TrimSuffix(pkgpath, ".a")
++		pkg.Imports[i] = pkgpath
++
++		p.scanImport(pkgpath)
++	}
++}
++
++func (p *Prog) addSym(s *Sym) {
++	pkg := s.Package
++	if pkg == nil {
++		pkg = p.Packages[""]
++		if pkg == nil {
++			pkg = &Package{}
++			p.Packages[""] = pkg
++		}
++		s.Package = pkg
++	}
++	pkg.Syms = append(pkg.Syms, s)
++	p.Syms[s.SymID] = s
++	p.SymOrder = append(p.SymOrder, s)
++}
++
++// scanImport finds the object file for the given import path and then scans it.
++func (p *Prog) scanImport(pkgpath string) {
++	if p.Packages[pkgpath] != nil {
++		return // already loaded
++	}
++
++	// TODO(rsc): Implement correct search to find file.
++	p.scanFile(pkgpath, p.pkgdir+"/"+pkgpath+".a")
++}
+diff --git a/src/cmd/newlink/testdata/Makefile b/src/cmd/newlink/testdata/Makefile
+new file mode 100644
+index 0000000..d5df474
+--- /dev/null
++++ b/src/cmd/newlink/testdata/Makefile
+@@ -0,0 +1,15 @@
++ALL=\
++	autosection.6\
++	autoweak.6\
++	dead.6\
++	hello.6\
++	layout.6\
++	pclntab.6\
++
++all: $(ALL)
++
++%.6: %.s
++	GOARCH=amd64 GOOS=darwin go tool asm -o $*.6 -I $(shell go env GOROOT)/pkg/include -trimpath=$(shell pwd) $*.s
++
++pclntab.s: genpcln.go
++	go run genpcln.go >pclntab.s
+diff --git a/src/cmd/newlink/testdata/autosection.6 b/src/cmd/newlink/testdata/autosection.6
+new file mode 100644
+index 0000000..702cab6
+Binary files /dev/null and b/src/cmd/newlink/testdata/autosection.6 differ
+diff --git a/src/cmd/newlink/testdata/autosection.s b/src/cmd/newlink/testdata/autosection.s
+new file mode 100644
+index 0000000..e0cb217
+--- /dev/null
++++ b/src/cmd/newlink/testdata/autosection.s
+@@ -0,0 +1,60 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Test of section-named symbols.
++
++#include "textflag.h"
++
++TEXT start(SB),7,$0
++	MOVQ $autotab(SB),AX
++	MOVQ $autoptr(SB),AX
++	RET
++
++GLOBL zero(SB), $8
++
++GLOBL zeronoptr(SB), NOPTR, $16
++
++// text
++DATA autotab+0x00(SB)/8, $runtime·text(SB)
++DATA autotab+0x08(SB)/8, $start(SB)
++DATA autotab+0x10(SB)/8, $runtime·etext(SB)
++DATA autotab+0x18(SB)/8, $start+16(SB)
++
++// data
++DATA autotab+0x20(SB)/8, $runtime·data(SB)
++DATA autotab+0x28(SB)/8, $autotab(SB)
++DATA autotab+0x30(SB)/8, $runtime·edata(SB)
++DATA autotab+0x38(SB)/8, $nonzero+4(SB)
++
++// bss
++DATA autotab+0x40(SB)/8, $runtime·bss(SB)
++DATA autotab+0x48(SB)/8, $zero(SB)
++DATA autotab+0x50(SB)/8, $runtime·ebss(SB)
++DATA autotab+0x58(SB)/8, $zero+8(SB)
++
++// noptrdata
++DATA autotab+0x60(SB)/8, $runtime·noptrdata(SB)
++DATA autotab+0x68(SB)/8, $nonzeronoptr(SB)
++DATA autotab+0x70(SB)/8, $runtime·enoptrdata(SB)
++DATA autotab+0x78(SB)/8, $nonzeronoptr+8(SB)
++
++// noptrbss
++DATA autotab+0x80(SB)/8, $runtime·noptrbss(SB)
++DATA autotab+0x88(SB)/8, $zeronoptr(SB)
++DATA autotab+0x90(SB)/8, $runtime·enoptrbss(SB)
++DATA autotab+0x98(SB)/8, $zeronoptr+16(SB)
++
++// end
++DATA autotab+0xa0(SB)/8, $runtime·end(SB)
++DATA autotab+0xa8(SB)/8, $zeronoptr+16(SB)
++
++GLOBL autotab(SB), $0xb0
++
++DATA nonzero(SB)/4, $1
++GLOBL nonzero(SB), $4
++
++DATA nonzeronoptr(SB)/8, $2
++GLOBL nonzeronoptr(SB), NOPTR, $8
++
++GLOBL autoptr(SB), $0
+diff --git a/src/cmd/newlink/testdata/autoweak.6 b/src/cmd/newlink/testdata/autoweak.6
+new file mode 100644
+index 0000000..5c68cdb
+Binary files /dev/null and b/src/cmd/newlink/testdata/autoweak.6 differ
+diff --git a/src/cmd/newlink/testdata/autoweak.s b/src/cmd/newlink/testdata/autoweak.s
+new file mode 100644
+index 0000000..2d11330
+--- /dev/null
++++ b/src/cmd/newlink/testdata/autoweak.s
+@@ -0,0 +1,30 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Test of go.weak symbols.
++
++TEXT start(SB),7,$0
++	MOVQ $autotab(SB),AX
++	MOVQ $autoptr(SB),AX
++	RET
++
++// go.weak.sym should resolve to sym, because sym is in the binary.
++DATA autotab+0(SB)/8, $go·weak·sym(SB)
++DATA autotab+8(SB)/8, $sym(SB)
++
++// go.weak.missingsym should resolve to 0, because missingsym is not in the binary.
++DATA autotab+16(SB)/8, $go·weak·missingsym(SB)
++DATA autotab+24(SB)/8, $0
++
++// go.weak.deadsym should resolve to 0, because deadsym is discarded during dead code removal
++DATA autotab+32(SB)/8, $go·weak·deadsym(SB)
++DATA autotab+40(SB)/8, $0
++
++GLOBL autotab(SB), $48
++
++GLOBL sym(SB), $1
++
++GLOBL deadsym(SB), $1
++
++GLOBL autoptr(SB), $0
+diff --git a/src/cmd/newlink/testdata/dead.6 b/src/cmd/newlink/testdata/dead.6
+new file mode 100644
+index 0000000..6f14aa2
+Binary files /dev/null and b/src/cmd/newlink/testdata/dead.6 differ
+diff --git a/src/cmd/newlink/testdata/dead.s b/src/cmd/newlink/testdata/dead.s
+new file mode 100644
+index 0000000..86f3136
+--- /dev/null
++++ b/src/cmd/newlink/testdata/dead.s
+@@ -0,0 +1,48 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Test of dead code removal.
++// Symbols with names beginning with dead_ should be discarded.
++// Others should be kept.
++
++TEXT start(SB),7,$0	// start symbol
++	MOVQ $data1<>(SB), AX
++	CALL text1(SB)
++	MOVQ $text2(SB), BX
++	RET
++
++TEXT text1(SB),7,$0
++	FUNCDATA $1, funcdata+4(SB)
++	RET
++
++TEXT text2(SB),7,$0
++	MOVQ $runtime·edata(SB),BX
++	RET
++
++DATA data1<>+0(SB)/8, $data2(SB)
++DATA data1<>+8(SB)/8, $data3(SB)
++GLOBL data1<>(SB), $16
++GLOBL data2(SB), $1
++GLOBL data3(SB), $1
++GLOBL funcdata(SB), $8
++
++TEXT dead_start(SB),7,$0
++	MOVQ $dead_data1(SB), AX
++	CALL dead_text1(SB)
++	MOVQ $dead_text2(SB), BX
++	RET
++
++TEXT dead_text1(SB),7,$0
++	FUNCDATA $1, dead_funcdata+4(SB)
++	RET
++
++TEXT dead_text2(SB),7,$0
++	RET
++
++DATA dead_data1+0(SB)/8, $dead_data2(SB)
++DATA dead_data1+8(SB)/8, $dead_data3(SB)
++GLOBL dead_data1(SB), $16
++GLOBL dead_data2(SB), $1
++GLOBL dead_data3(SB), $1
++GLOBL dead_funcdata(SB), $8
+diff --git a/src/cmd/newlink/testdata/genpcln.go b/src/cmd/newlink/testdata/genpcln.go
+new file mode 100644
+index 0000000..c10eaea
+--- /dev/null
++++ b/src/cmd/newlink/testdata/genpcln.go
+@@ -0,0 +1,112 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// This program generates a .s file using a pseudorandom
++// value stream for the runtime function data.
++// The pclntab test checks that the linked copy
++// still has the same pseudorandom value stream.
++
++package main
++
++import (
++	"fmt"
++	"math/rand"
++)
++
++func main() {
++	fmt.Printf("// generated by genpcln.go; do not edit\n\n")
++	for f := 0; f < 3; f++ {
++		r := rand.New(rand.NewSource(int64(f)))
++		file := "input"
++		line := 1
++		args := r.Intn(100) * 8
++		frame := 32 + r.Intn(32)/8*8
++		fmt.Printf("#line %d %q\n", line, file)
++		fmt.Printf("TEXT func%d(SB),7,$%d-%d\n", f, frame, args)
++		fmt.Printf("\tFUNCDATA $1, funcdata%d(SB)\n", f)
++		fmt.Printf("#line %d %q\n", line, file)
++		size := 200 + r.Intn(100)*8
++		spadj := 0
++		flushed := 0
++		firstpc := 4
++		flush := func(i int) {
++			for i-flushed >= 10 {
++				fmt.Printf("#line %d %q\n", line, file)
++				fmt.Printf("/*%#04x*/\tMOVQ $0x123456789, AX\n", firstpc+flushed)
++				flushed += 10
++			}
++			for i-flushed >= 5 {
++				fmt.Printf("#line %d %q\n", line, file)
++				fmt.Printf("/*%#04x*/\tMOVL $0x1234567, AX\n", firstpc+flushed)
++				flushed += 5
++			}
++			for i-flushed > 0 {
++				fmt.Printf("#line %d %q\n", line, file)
++				fmt.Printf("/*%#04x*/\tBYTE $0\n", firstpc+flushed)
++				flushed++
++			}
++		}
++		for i := 0; i < size; i++ {
++			// Possible SP adjustment.
++			if r.Intn(100) == 0 {
++				flush(i)
++				fmt.Printf("#line %d %q\n", line, file)
++				if spadj <= -32 || spadj < 32 && r.Intn(2) == 0 {
++					spadj += 8
++					fmt.Printf("/*%#04x*/\tPUSHQ AX\n", firstpc+i)
++				} else {
++					spadj -= 8
++					fmt.Printf("/*%#04x*/\tPOPQ AX\n", firstpc+i)
++				}
++				i += 1
++				flushed = i
++			}
++
++			// Possible PCFile change.
++			if r.Intn(100) == 0 {
++				flush(i)
++				file = fmt.Sprintf("file%d.s", r.Intn(10))
++				line = r.Intn(100) + 1
++			}
++
++			// Possible PCLine change.
++			if r.Intn(10) == 0 {
++				flush(i)
++				line = r.Intn(1000) + 1
++			}
++
++			// Possible PCData $1 change.
++			if r.Intn(100) == 0 {
++				flush(i)
++				fmt.Printf("/*%6s*/\tPCDATA $1, $%d\n", "", r.Intn(1000))
++			}
++
++			// Possible PCData $2 change.
++			if r.Intn(100) == 0 {
++				flush(i)
++				fmt.Printf("/*%6s*/\tPCDATA $2, $%d\n", "", r.Intn(1000))
++			}
++		}
++		flush(size)
++		for spadj < 0 {
++			fmt.Printf("\tPUSHQ AX\n")
++			spadj += 8
++		}
++		for spadj > 0 {
++			fmt.Printf("\tPOPQ AX\n")
++			spadj -= 8
++		}
++		fmt.Printf("\tRET\n")
++
++		fmt.Printf("\n")
++		fmt.Printf("GLOBL funcdata%d(SB), $16\n", f)
++	}
++
++	fmt.Printf("\nTEXT start(SB),7,$0\n")
++	for f := 0; f < 3; f++ {
++		fmt.Printf("\tCALL func%d(SB)\n", f)
++	}
++	fmt.Printf("\tMOVQ $runtime·pclntab(SB), AX\n")
++	fmt.Printf("\n\tRET\n")
++}
+diff --git a/src/cmd/newlink/testdata/hello.6 b/src/cmd/newlink/testdata/hello.6
+new file mode 100644
+index 0000000..825a2a6
+Binary files /dev/null and b/src/cmd/newlink/testdata/hello.6 differ
+diff --git a/src/cmd/newlink/testdata/hello.s b/src/cmd/newlink/testdata/hello.s
+new file mode 100644
+index 0000000..32ed675
+--- /dev/null
++++ b/src/cmd/newlink/testdata/hello.s
+@@ -0,0 +1,15 @@
++TEXT _rt0_go(SB),7,$0
++	MOVL $1, DI
++	MOVL $hello<>(SB), SI
++	MOVL $12, DX
++	MOVL $0x2000004, AX
++	SYSCALL
++	MOVL $0, DI
++	MOVL $0x2000001, AX
++	SYSCALL
++	RET
++
++DATA hello<>+0(SB)/4, $"hell"
++DATA hello<>+4(SB)/4, $"o wo"
++DATA hello<>+8(SB)/4, $"rld\n"
++GLOBL hello<>(SB), $12
+diff --git a/src/cmd/newlink/testdata/layout.6 b/src/cmd/newlink/testdata/layout.6
+new file mode 100644
+index 0000000..7e2a22b
+Binary files /dev/null and b/src/cmd/newlink/testdata/layout.6 differ
+diff --git a/src/cmd/newlink/testdata/layout.s b/src/cmd/newlink/testdata/layout.s
+new file mode 100644
+index 0000000..c3e55ef
+--- /dev/null
++++ b/src/cmd/newlink/testdata/layout.s
+@@ -0,0 +1,29 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Test of section assignment in layout.go.
++// Each symbol should end up in the section named by the symbol name prefix (up to the underscore).
++
++#include "textflag.h"
++
++TEXT text_start(SB),7,$0
++	MOVQ $rodata_sym(SB), AX
++	MOVQ $noptrdata_sym(SB), AX
++	MOVQ $data_sym(SB), AX
++	MOVQ $bss_sym(SB), AX
++	MOVQ $noptrbss_sym(SB), AX
++	RET
++
++DATA rodata_sym(SB)/4, $1
++GLOBL rodata_sym(SB), RODATA, $4
++
++DATA noptrdata_sym(SB)/4, $1
++GLOBL noptrdata_sym(SB), NOPTR, $4
++
++DATA data_sym(SB)/4, $1
++GLOBL data_sym(SB), $4
++
++GLOBL bss_sym(SB), $4
++
++GLOBL noptrbss_sym(SB), NOPTR, $4
+diff --git a/src/cmd/newlink/testdata/link.hello.darwin.amd64 b/src/cmd/newlink/testdata/link.hello.darwin.amd64
+new file mode 100644
+index 0000000..4c62eb1
+--- /dev/null
++++ b/src/cmd/newlink/testdata/link.hello.darwin.amd64
+@@ -0,0 +1,55 @@
++00000000  cf fa ed fe 07 00 00 01  03 00 00 00 02 00 00 00  |................|
++00000010  04 00 00 00 d0 02 00 00  01 00 00 00 00 00 00 00  |................|
++00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
++00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
++00000040  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00000060  00 00 00 00 00 00 00 00  19 00 00 00 38 01 00 00  |............8...|
++00000070  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000080  00 10 00 00 00 00 00 00  c0 10 00 00 00 00 00 00  |................|
++00000090  00 00 00 00 00 00 00 00  c0 10 00 00 00 00 00 00  |................|
++000000a0  07 00 00 00 05 00 00 00  03 00 00 00 00 00 00 00  |................|
++000000b0  5f 5f 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |__text..........|
++000000c0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++000000d0  00 20 00 00 00 00 00 00  30 00 00 00 00 00 00 00  |. ......0.......|
++000000e0  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++000000f0  00 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000100  5f 5f 72 6f 64 61 74 61  00 00 00 00 00 00 00 00  |__rodata........|
++00000110  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000120  30 20 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |0 ..............|
++00000130  30 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |0...............|
++*
++00000150  5f 5f 66 75 6e 63 74 61  62 00 00 00 00 00 00 00  |__functab.......|
++00000160  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000170  30 20 00 00 00 00 00 00  90 00 00 00 00 00 00 00  |0 ..............|
++00000180  30 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |0...............|
++*
++000001a0  19 00 00 00 98 00 00 00  5f 5f 44 41 54 41 00 00  |........__DATA..|
++000001b0  00 00 00 00 00 00 00 00  00 30 00 00 00 00 00 00  |.........0......|
++000001c0  0c 00 00 00 00 00 00 00  00 20 00 00 00 00 00 00  |......... ......|
++000001d0  0c 00 00 00 00 00 00 00  03 00 00 00 03 00 00 00  |................|
++000001e0  01 00 00 00 00 00 00 00  5f 5f 64 61 74 61 00 00  |........__data..|
++000001f0  00 00 00 00 00 00 00 00  5f 5f 44 41 54 41 00 00  |........__DATA..|
++00000200  00 00 00 00 00 00 00 00  00 30 00 00 00 00 00 00  |.........0......|
++00000210  0c 00 00 00 00 00 00 00  00 20 00 00 00 00 00 00  |......... ......|
++*
++00000230  00 00 00 00 00 00 00 00  05 00 00 00 b8 00 00 00  |................|
++00000240  04 00 00 00 2a 00 00 00  00 00 00 00 00 00 00 00  |....*...........|
++*
++000002c0  00 00 00 00 00 00 00 00  00 20 00 00 00 00 00 00  |......... ......|
++*
++00001000  bf 01 00 00 00 8d 35 f5  0f 00 00 ba 0c 00 00 00  |......5.........|
++00001010  b8 04 00 00 02 0f 05 31  ff b8 01 00 00 02 0f 05  |.......1........|
++00001020  c3 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00001030  fb ff ff ff 00 00 01 08  01 00 00 00 00 00 00 00  |................|
++00001040  00 20 00 00 00 00 00 00  30 00 00 00 00 00 00 00  |. ......0.......|
++00001050  30 20 00 00 00 00 00 00  80 00 00 00 00 00 00 00  |0 ..............|
++00001060  00 20 00 00 00 00 00 00  58 00 00 00 00 00 00 80  |. ......X.......|
++00001070  08 00 00 00 60 00 00 00  63 00 00 00 66 00 00 00  |....`...c...f...|
++00001080  00 00 00 00 00 00 00 00  5f 72 74 30 5f 67 6f 00  |........_rt0_go.|
++00001090  02 30 00 04 30 00 06 05  02 06 02 05 02 05 02 02  |.0..0...........|
++000010a0  02 02 02 05 02 02 02 10  00 00 00 00 00 00 00 00  |................|
++000010b0  02 00 00 00 88 00 00 00  68 65 6c 6c 6f 2e 73 00  |........hello.s.|
++*
++00002000  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a              |hello world.|
++0000200c
+diff --git a/src/cmd/newlink/testdata/macho.amd64.exit9 b/src/cmd/newlink/testdata/macho.amd64.exit9
+new file mode 100644
+index 0000000..1adc814
+--- /dev/null
++++ b/src/cmd/newlink/testdata/macho.amd64.exit9
+@@ -0,0 +1,24 @@
++00000000  cf fa ed fe 07 00 00 01  03 00 00 00 02 00 00 00  |................|
++00000010  03 00 00 00 98 01 00 00  01 00 00 00 00 00 00 00  |................|
++00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
++00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
++00000040  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000060  00 00 00 00 00 00 00 00  19 00 00 00 98 00 00 00  |................|
++00000070  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000080  00 10 00 00 00 00 00 00  0d 10 00 00 00 00 00 00  |................|
++00000090  00 00 00 00 00 00 00 00  0d 10 00 00 00 00 00 00  |................|
++000000a0  07 00 00 00 05 00 00 00  01 00 00 00 00 00 00 00  |................|
++000000b0  5f 5f 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |__text..........|
++000000c0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++000000d0  00 20 00 00 00 00 00 00  0d 00 00 00 00 00 00 00  |. ..............|
++000000e0  00 10 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
++000000f0  00 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000100  05 00 00 00 b8 00 00 00  04 00 00 00 2a 00 00 00  |............*...|
++00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00000190  00 20 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
++000001a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00001000  b8 01 00 00 02 bf 09 00  00 00 0f 05 f4           |.............|
++0000100d
+diff --git a/src/cmd/newlink/testdata/macho.amd64.hello b/src/cmd/newlink/testdata/macho.amd64.hello
+new file mode 100644
+index 0000000..45e70d0
+--- /dev/null
++++ b/src/cmd/newlink/testdata/macho.amd64.hello
+@@ -0,0 +1,39 @@
++00000000  cf fa ed fe 07 00 00 01  03 00 00 00 02 00 00 00  |................|
++00000010  04 00 00 00 30 02 00 00  01 00 00 00 00 00 00 00  |....0...........|
++00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
++00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
++00000040  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000060  00 00 00 00 00 00 00 00  19 00 00 00 98 00 00 00  |................|
++00000070  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000080  00 10 00 00 00 00 00 00  23 10 00 00 00 00 00 00  |........#.......|
++00000090  00 00 00 00 00 00 00 00  23 10 00 00 00 00 00 00  |........#.......|
++000000a0  07 00 00 00 05 00 00 00  01 00 00 00 00 00 00 00  |................|
++000000b0  5f 5f 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |__text..........|
++000000c0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++000000d0  00 20 00 00 00 00 00 00  23 00 00 00 00 00 00 00  |. ......#.......|
++000000e0  00 10 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
++000000f0  00 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000100  19 00 00 00 98 00 00 00  5f 5f 44 41 54 41 00 00  |........__DATA..|
++00000110  00 00 00 00 00 00 00 00  00 30 00 00 00 00 00 00  |.........0......|
++00000120  0c 00 00 00 00 00 00 00  00 20 00 00 00 00 00 00  |......... ......|
++00000130  0c 00 00 00 00 00 00 00  03 00 00 00 03 00 00 00  |................|
++00000140  01 00 00 00 00 00 00 00  5f 5f 64 61 74 61 00 00  |........__data..|
++00000150  00 00 00 00 00 00 00 00  5f 5f 44 41 54 41 00 00  |........__DATA..|
++00000160  00 00 00 00 00 00 00 00  00 30 00 00 00 00 00 00  |.........0......|
++00000170  0c 00 00 00 00 00 00 00  00 20 00 00 06 00 00 00  |......... ......|
++00000180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000190  00 00 00 00 00 00 00 00  05 00 00 00 b8 00 00 00  |................|
++000001a0  04 00 00 00 2a 00 00 00  00 00 00 00 00 00 00 00  |....*...........|
++000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00000220  00 00 00 00 00 00 00 00  00 20 00 00 00 00 00 00  |......... ......|
++00000230  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00001000  b8 04 00 00 02 bf 01 00  00 00 be 00 30 00 00 ba  |............0...|
++00001010  0c 00 00 00 0f 05 b8 01  00 00 02 bf 09 00 00 00  |................|
++00001020  0f 05 f4 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00001030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00002000  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a              |hello world.|
++0000200c
+diff --git a/src/cmd/newlink/testdata/macho.amd64.helloro b/src/cmd/newlink/testdata/macho.amd64.helloro
+new file mode 100644
+index 0000000..4b70fbd
+--- /dev/null
++++ b/src/cmd/newlink/testdata/macho.amd64.helloro
+@@ -0,0 +1,34 @@
++00000000  cf fa ed fe 07 00 00 01  03 00 00 00 02 00 00 00  |................|
++00000010  03 00 00 00 e8 01 00 00  01 00 00 00 00 00 00 00  |................|
++00000020  19 00 00 00 48 00 00 00  5f 5f 50 41 47 45 5a 45  |....H...__PAGEZE|
++00000030  52 4f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |RO..............|
++00000040  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000060  00 00 00 00 00 00 00 00  19 00 00 00 e8 00 00 00  |................|
++00000070  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000080  00 10 00 00 00 00 00 00  0c 20 00 00 00 00 00 00  |......... ......|
++00000090  00 00 00 00 00 00 00 00  0c 20 00 00 00 00 00 00  |......... ......|
++000000a0  07 00 00 00 05 00 00 00  02 00 00 00 00 00 00 00  |................|
++000000b0  5f 5f 74 65 78 74 00 00  00 00 00 00 00 00 00 00  |__text..........|
++000000c0  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++000000d0  00 20 00 00 00 00 00 00  23 00 00 00 00 00 00 00  |. ......#.......|
++000000e0  00 10 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
++000000f0  00 04 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000100  5f 5f 72 6f 64 61 74 61  00 00 00 00 00 00 00 00  |__rodata........|
++00000110  5f 5f 54 45 58 54 00 00  00 00 00 00 00 00 00 00  |__TEXT..........|
++00000120  00 30 00 00 00 00 00 00  0c 00 00 00 00 00 00 00  |.0..............|
++00000130  00 20 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
++00000140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00000150  05 00 00 00 b8 00 00 00  04 00 00 00 2a 00 00 00  |............*...|
++00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++000001e0  00 20 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |. ..............|
++000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00001000  b8 04 00 00 02 bf 01 00  00 00 be 00 30 00 00 ba  |............0...|
++00001010  0c 00 00 00 0f 05 b8 01  00 00 02 bf 00 00 00 00  |................|
++00001020  0f 05 f4 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++00001030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
++*
++00002000  68 65 6c 6c 6f 20 77 6f  72 6c 64 0a              |hello world.|
++0000200c
+diff --git a/src/cmd/newlink/testdata/pclntab.6 b/src/cmd/newlink/testdata/pclntab.6
+new file mode 100644
+index 0000000..d029bb7
+Binary files /dev/null and b/src/cmd/newlink/testdata/pclntab.6 differ
+diff --git a/src/cmd/newlink/testdata/pclntab.s b/src/cmd/newlink/testdata/pclntab.s
+new file mode 100644
+index 0000000..12dac70
+--- /dev/null
++++ b/src/cmd/newlink/testdata/pclntab.s
+@@ -0,0 +1,1751 @@
++// generated by genpcln.go; do not edit
++
++#line 1 "input"
++TEXT func0(SB),7,$48-592
++	FUNCDATA $1, funcdata0(SB)
++#line 1 "input"
++#line 1 "input"
++/*0x0004*/	MOVL $0x1234567, AX
++#line 1 "input"
++/*0x0009*/	BYTE $0
++/*      */	PCDATA $1, $110
++#line 1 "input"
++/*0x000a*/	BYTE $0
++#line 1 "input"
++/*0x000b*/	BYTE $0
++/*      */	PCDATA $1, $422
++#line 1 "input"
++/*0x000c*/	BYTE $0
++#line 1 "input"
++/*0x000d*/	BYTE $0
++#line 1 "input"
++/*0x000e*/	POPQ AX
++#line 1 "input"
++/*0x000f*/	MOVL $0x1234567, AX
++#line 1 "input"
++/*0x0014*/	BYTE $0
++#line 1 "input"
++/*0x0015*/	BYTE $0
++#line 1 "input"
++/*0x0016*/	BYTE $0
++#line 542 "input"
++/*0x0017*/	BYTE $0
++#line 960 "input"
++/*0x0018*/	MOVL $0x1234567, AX
++#line 960 "input"
++/*0x001d*/	BYTE $0
++#line 960 "input"
++/*0x001e*/	PUSHQ AX
++#line 960 "input"
++/*0x001f*/	BYTE $0
++#line 960 "input"
++/*0x0020*/	BYTE $0
++#line 594 "input"
++/*0x0021*/	BYTE $0
++#line 671 "input"
++/*0x0022*/	MOVL $0x1234567, AX
++#line 671 "input"
++/*0x0027*/	BYTE $0
++#line 671 "input"
++/*0x0028*/	BYTE $0
++#line 230 "input"
++/*0x0029*/	BYTE $0
++#line 230 "input"
++/*0x002a*/	BYTE $0
++#line 413 "input"
++/*0x002b*/	BYTE $0
++#line 413 "input"
++/*0x002c*/	BYTE $0
++#line 413 "input"
++/*0x002d*/	BYTE $0
++#line 729 "input"
++/*0x002e*/	BYTE $0
++#line 729 "input"
++/*0x002f*/	BYTE $0
++#line 729 "input"
++/*0x0030*/	BYTE $0
++#line 948 "input"
++/*0x0031*/	BYTE $0
++#line 11 "input"
++/*0x0032*/	MOVQ $0x123456789, AX
++#line 11 "input"
++/*0x003c*/	MOVL $0x1234567, AX
++#line 11 "input"
++/*0x0041*/	BYTE $0
++#line 11 "input"
++/*0x0042*/	BYTE $0
++#line 11 "input"
++/*0x0043*/	POPQ AX
++/*      */	PCDATA $2, $342
++#line 11 "input"
++/*0x0044*/	MOVQ $0x123456789, AX
++#line 11 "input"
++/*0x004e*/	MOVQ $0x123456789, AX
++#line 11 "input"
++/*0x0058*/	MOVL $0x1234567, AX
++#line 11 "input"
++/*0x005d*/	BYTE $0
++#line 11 "input"
++/*0x005e*/	BYTE $0
++#line 70 "input"
++/*0x005f*/	BYTE $0
++#line 70 "input"
++/*0x0060*/	BYTE $0
++#line 70 "input"
++/*0x0061*/	BYTE $0
++#line 18 "input"
++/*0x0062*/	MOVQ $0x123456789, AX
++#line 18 "input"
++/*0x006c*/	MOVL $0x1234567, AX
++#line 18 "input"
++/*0x0071*/	BYTE $0
++#line 814 "input"
++/*0x0072*/	BYTE $0
++#line 814 "input"
++/*0x0073*/	PUSHQ AX
++#line 763 "input"
++/*0x0074*/	BYTE $0
++#line 763 "input"
++/*0x0075*/	BYTE $0
++#line 763 "input"
++/*0x0076*/	BYTE $0
++#line 530 "input"
++/*0x0077*/	BYTE $0
++#line 530 "input"
++/*0x0078*/	BYTE $0
++#line 530 "input"
++/*0x0079*/	BYTE $0
++#line 530 "input"
++/*0x007a*/	BYTE $0
++#line 985 "input"
++/*0x007b*/	BYTE $0
++#line 985 "input"
++/*0x007c*/	BYTE $0
++#line 985 "input"
++/*0x007d*/	BYTE $0
++#line 985 "input"
++/*0x007e*/	PUSHQ AX
++#line 985 "input"
++/*0x007f*/	MOVL $0x1234567, AX
++#line 958 "input"
++/*0x0084*/	BYTE $0
++#line 368 "input"
++/*0x0085*/	MOVQ $0x123456789, AX
++#line 368 "input"
++/*0x008f*/	MOVL $0x1234567, AX
++#line 368 "input"
++/*0x0094*/	BYTE $0
++#line 368 "input"
++/*0x0095*/	BYTE $0
++#line 368 "input"
++/*0x0096*/	BYTE $0
++#line 368 "input"
++/*0x0097*/	BYTE $0
++#line 75 "file0.s"
++/*0x0098*/	BYTE $0
++#line 75 "file0.s"
++/*0x0099*/	BYTE $0
++#line 75 "file0.s"
++/*0x009a*/	BYTE $0
++#line 75 "file0.s"
++/*0x009b*/	BYTE $0
++#line 588 "file0.s"
++/*0x009c*/	MOVQ $0x123456789, AX
++#line 187 "file0.s"
++/*0x00a6*/	MOVQ $0x123456789, AX
++#line 187 "file0.s"
++/*0x00b0*/	BYTE $0
++#line 202 "file0.s"
++/*0x00b1*/	MOVL $0x1234567, AX
++#line 202 "file0.s"
++/*0x00b6*/	BYTE $0
++#line 887 "file0.s"
++/*0x00b7*/	MOVL $0x1234567, AX
++#line 887 "file0.s"
++/*0x00bc*/	BYTE $0
++#line 887 "file0.s"
++/*0x00bd*/	BYTE $0
++#line 480 "file0.s"
++/*0x00be*/	MOVL $0x1234567, AX
++#line 480 "file0.s"
++/*0x00c3*/	BYTE $0
++#line 40 "file8.s"
++/*0x00c4*/	BYTE $0
++#line 17 "file0.s"
++/*0x00c5*/	MOVQ $0x123456789, AX
++#line 17 "file0.s"
++/*0x00cf*/	BYTE $0
++#line 17 "file0.s"
++/*0x00d0*/	BYTE $0
++#line 17 "file0.s"
++/*0x00d1*/	BYTE $0
++#line 17 "file0.s"
++/*0x00d2*/	BYTE $0
++#line 436 "file0.s"
++/*0x00d3*/	MOVL $0x1234567, AX
++#line 436 "file0.s"
++/*0x00d8*/	BYTE $0
++#line 436 "file0.s"
++/*0x00d9*/	BYTE $0
++#line 346 "file0.s"
++/*0x00da*/	BYTE $0
++#line 346 "file0.s"
++/*0x00db*/	BYTE $0
++#line 346 "file0.s"
++/*0x00dc*/	BYTE $0
++#line 812 "file0.s"
++/*0x00dd*/	BYTE $0
++#line 812 "file0.s"
++/*0x00de*/	BYTE $0
++#line 812 "file0.s"
++/*0x00df*/	BYTE $0
++#line 812 "file0.s"
++/*0x00e0*/	BYTE $0
++#line 94 "file1.s"
++/*0x00e1*/	BYTE $0
++#line 94 "file1.s"
++/*0x00e2*/	BYTE $0
++#line 165 "file1.s"
++/*0x00e3*/	MOVL $0x1234567, AX
++#line 165 "file1.s"
++/*0x00e8*/	BYTE $0
++#line 456 "file1.s"
++/*0x00e9*/	BYTE $0
++#line 810 "file1.s"
++/*0x00ea*/	BYTE $0
++#line 722 "file1.s"
++/*0x00eb*/	BYTE $0
++#line 722 "file1.s"
++/*0x00ec*/	BYTE $0
++#line 722 "file1.s"
++/*0x00ed*/	BYTE $0
++#line 722 "file1.s"
++/*0x00ee*/	BYTE $0
++#line 722 "file1.s"
++/*0x00ef*/	PUSHQ AX
++#line 722 "file1.s"
++/*0x00f0*/	BYTE $0
++#line 722 "file1.s"
++/*0x00f1*/	BYTE $0
++#line 722 "file1.s"
++/*0x00f2*/	BYTE $0
++#line 722 "file1.s"
++/*0x00f3*/	BYTE $0
++/*      */	PCDATA $2, $246
++#line 722 "file1.s"
++/*0x00f4*/	MOVQ $0x123456789, AX
++#line 722 "file1.s"
++/*0x00fe*/	MOVQ $0x123456789, AX
++#line 722 "file1.s"
++/*0x0108*/	MOVL $0x1234567, AX
++#line 722 "file1.s"
++/*0x010d*/	BYTE $0
++#line 722 "file1.s"
++/*0x010e*/	BYTE $0
++#line 497 "file1.s"
++/*0x010f*/	MOVQ $0x123456789, AX
++#line 497 "file1.s"
++/*0x0119*/	MOVQ $0x123456789, AX
++#line 497 "file1.s"
++/*0x0123*/	MOVQ $0x123456789, AX
++#line 497 "file1.s"
++/*0x012d*/	MOVL $0x1234567, AX
++#line 497 "file1.s"
++/*0x0132*/	BYTE $0
++#line 686 "file1.s"
++/*0x0133*/	BYTE $0
++#line 686 "file1.s"
++/*0x0134*/	BYTE $0
++#line 248 "file1.s"
++/*0x0135*/	BYTE $0
++#line 248 "file1.s"
++/*0x0136*/	BYTE $0
++#line 248 "file1.s"
++/*0x0137*/	BYTE $0
++#line 248 "file1.s"
++/*0x0138*/	BYTE $0
++#line 307 "file1.s"
++/*0x0139*/	BYTE $0
++#line 220 "file1.s"
++/*0x013a*/	MOVL $0x1234567, AX
++#line 220 "file1.s"
++/*0x013f*/	BYTE $0
++#line 220 "file1.s"
++/*0x0140*/	BYTE $0
++#line 467 "file1.s"
++/*0x0141*/	MOVQ $0x123456789, AX
++#line 467 "file1.s"
++/*0x014b*/	BYTE $0
++#line 467 "file1.s"
++/*0x014c*/	BYTE $0
++#line 467 "file1.s"
++/*0x014d*/	BYTE $0
++#line 467 "file1.s"
++/*0x014e*/	BYTE $0
++#line 786 "file1.s"
++/*0x014f*/	MOVL $0x1234567, AX
++#line 251 "file1.s"
++/*0x0154*/	BYTE $0
++/*      */	PCDATA $2, $64
++#line 251 "file1.s"
++/*0x0155*/	BYTE $0
++#line 251 "file1.s"
++/*0x0156*/	BYTE $0
++#line 251 "file1.s"
++/*0x0157*/	BYTE $0
++#line 618 "file1.s"
++/*0x0158*/	MOVQ $0x123456789, AX
++/*      */	PCDATA $1, $686
++#line 618 "file1.s"
++/*0x0162*/	BYTE $0
++#line 618 "file1.s"
++/*0x0163*/	BYTE $0
++#line 618 "file1.s"
++/*0x0164*/	BYTE $0
++#line 618 "file1.s"
++/*0x0165*/	PUSHQ AX
++/*      */	PCDATA $2, $915
++#line 618 "file1.s"
++/*0x0166*/	BYTE $0
++#line 618 "file1.s"
++/*0x0167*/	BYTE $0
++#line 618 "file1.s"
++/*0x0168*/	BYTE $0
++#line 618 "file1.s"
++/*0x0169*/	BYTE $0
++#line 230 "file1.s"
++/*0x016a*/	BYTE $0
++#line 823 "file1.s"
++/*0x016b*/	BYTE $0
++#line 145 "file1.s"
++/*0x016c*/	MOVQ $0x123456789, AX
++#line 145 "file1.s"
++/*0x0176*/	BYTE $0
++#line 145 "file1.s"
++/*0x0177*/	BYTE $0
++#line 675 "file1.s"
++/*0x0178*/	BYTE $0
++#line 62 "file9.s"
++/*0x0179*/	BYTE $0
++/*      */	PCDATA $2, $768
++#line 62 "file9.s"
++/*0x017a*/	BYTE $0
++#line 62 "file9.s"
++/*0x017b*/	BYTE $0
++#line 29 "file9.s"
++/*0x017c*/	BYTE $0
++#line 29 "file9.s"
++/*0x017d*/	BYTE $0
++#line 29 "file9.s"
++/*0x017e*/	BYTE $0
++#line 29 "file9.s"
++/*0x017f*/	BYTE $0
++#line 65 "file4.s"
++/*0x0180*/	BYTE $0
++#line 77 "file3.s"
++/*0x0181*/	MOVL $0x1234567, AX
++#line 77 "file3.s"
++/*0x0186*/	BYTE $0
++#line 77 "file3.s"
++/*0x0187*/	BYTE $0
++#line 77 "file3.s"
++/*0x0188*/	BYTE $0
++#line 307 "file3.s"
++/*0x0189*/	MOVQ $0x123456789, AX
++#line 307 "file3.s"
++/*0x0193*/	BYTE $0
++#line 654 "file3.s"
++/*0x0194*/	BYTE $0
++#line 654 "file3.s"
++/*0x0195*/	BYTE $0
++#line 115 "file3.s"
++/*0x0196*/	MOVL $0x1234567, AX
++#line 115 "file3.s"
++/*0x019b*/	BYTE $0
++#line 115 "file3.s"
++/*0x019c*/	BYTE $0
++#line 115 "file3.s"
++/*0x019d*/	BYTE $0
++#line 115 "file3.s"
++/*0x019e*/	BYTE $0
++#line 154 "file3.s"
++/*0x019f*/	MOVQ $0x123456789, AX
++#line 166 "file3.s"
++/*0x01a9*/	BYTE $0
++#line 166 "file3.s"
++/*0x01aa*/	BYTE $0
++#line 166 "file3.s"
++/*0x01ab*/	BYTE $0
++/*      */	PCDATA $1, $523
++#line 166 "file3.s"
++/*0x01ac*/	MOVL $0x1234567, AX
++#line 166 "file3.s"
++/*0x01b1*/	BYTE $0
++#line 779 "file3.s"
++/*0x01b2*/	BYTE $0
++#line 779 "file3.s"
++/*0x01b3*/	BYTE $0
++#line 515 "file3.s"
++/*0x01b4*/	BYTE $0
++#line 515 "file3.s"
++/*0x01b5*/	BYTE $0
++#line 369 "file3.s"
++/*0x01b6*/	MOVL $0x1234567, AX
++#line 369 "file3.s"
++/*0x01bb*/	BYTE $0
++#line 369 "file3.s"
++/*0x01bc*/	BYTE $0
++#line 369 "file3.s"
++/*0x01bd*/	BYTE $0
++#line 680 "file3.s"
++/*0x01be*/	BYTE $0
++#line 680 "file3.s"
++/*0x01bf*/	BYTE $0
++#line 680 "file3.s"
++/*0x01c0*/	BYTE $0
++#line 680 "file3.s"
++/*0x01c1*/	BYTE $0
++#line 131 "file3.s"
++/*0x01c2*/	MOVQ $0x123456789, AX
++#line 131 "file3.s"
++/*0x01cc*/	BYTE $0
++#line 131 "file3.s"
++/*0x01cd*/	BYTE $0
++#line 131 "file3.s"
++/*0x01ce*/	BYTE $0
++#line 131 "file3.s"
++/*0x01cf*/	BYTE $0
++#line 848 "file3.s"
++/*0x01d0*/	BYTE $0
++#line 848 "file3.s"
++/*0x01d1*/	BYTE $0
++#line 848 "file3.s"
++/*0x01d2*/	POPQ AX
++#line 848 "file3.s"
++/*0x01d3*/	BYTE $0
++#line 848 "file3.s"
++/*0x01d4*/	BYTE $0
++#line 848 "file3.s"
++/*0x01d5*/	BYTE $0
++/*      */	PCDATA $1, $86
++#line 848 "file3.s"
++/*0x01d6*/	MOVL $0x1234567, AX
++#line 438 "file3.s"
++/*0x01db*/	MOVQ $0x123456789, AX
++#line 438 "file3.s"
++/*0x01e5*/	MOVL $0x1234567, AX
++#line 5 "file3.s"
++/*0x01ea*/	BYTE $0
++#line 5 "file3.s"
++/*0x01eb*/	BYTE $0
++#line 531 "file3.s"
++/*0x01ec*/	MOVQ $0x123456789, AX
++#line 531 "file3.s"
++/*0x01f6*/	MOVQ $0x123456789, AX
++#line 531 "file3.s"
++/*0x0200*/	MOVQ $0x123456789, AX
++#line 531 "file3.s"
++/*0x020a*/	MOVL $0x1234567, AX
++#line 863 "file3.s"
++/*0x020f*/	BYTE $0
++#line 733 "file3.s"
++/*0x0210*/	MOVQ $0x123456789, AX
++#line 166 "file3.s"
++/*0x021a*/	MOVQ $0x123456789, AX
++#line 166 "file3.s"
++/*0x0224*/	BYTE $0
++#line 166 "file3.s"
++/*0x0225*/	BYTE $0
++#line 166 "file3.s"
++/*0x0226*/	BYTE $0
++#line 166 "file3.s"
++/*0x0227*/	BYTE $0
++#line 54 "file3.s"
++/*0x0228*/	MOVQ $0x123456789, AX
++#line 54 "file3.s"
++/*0x0232*/	BYTE $0
++#line 54 "file3.s"
++/*0x0233*/	BYTE $0
++#line 54 "file3.s"
++/*0x0234*/	BYTE $0
++#line 20 "file4.s"
++/*0x0235*/	BYTE $0
++#line 20 "file4.s"
++/*0x0236*/	BYTE $0
++#line 546 "file4.s"
++/*0x0237*/	BYTE $0
++#line 546 "file4.s"
++/*0x0238*/	BYTE $0
++#line 74 "file4.s"
++/*0x0239*/	BYTE $0
++#line 31 "file4.s"
++/*0x023a*/	BYTE $0
++#line 31 "file4.s"
++/*0x023b*/	BYTE $0
++#line 31 "file4.s"
++/*0x023c*/	BYTE $0
++#line 31 "file4.s"
++/*0x023d*/	BYTE $0
++#line 834 "file4.s"
++/*0x023e*/	BYTE $0
++#line 834 "file4.s"
++/*0x023f*/	BYTE $0
++#line 519 "file4.s"
++/*0x0240*/	MOVL $0x1234567, AX
++#line 342 "file4.s"
++/*0x0245*/	BYTE $0
++#line 342 "file4.s"
++/*0x0246*/	BYTE $0
++#line 342 "file4.s"
++/*0x0247*/	BYTE $0
++#line 458 "file4.s"
++/*0x0248*/	BYTE $0
++#line 458 "file4.s"
++/*0x0249*/	BYTE $0
++#line 458 "file4.s"
++/*0x024a*/	BYTE $0
++#line 458 "file4.s"
++/*0x024b*/	BYTE $0
++#line 13 "file9.s"
++/*0x024c*/	BYTE $0
++#line 13 "file9.s"
++/*0x024d*/	BYTE $0
++#line 13 "file9.s"
++/*0x024e*/	BYTE $0
++#line 365 "file9.s"
++/*0x024f*/	BYTE $0
++#line 749 "file9.s"
++/*0x0250*/	MOVL $0x1234567, AX
++#line 749 "file9.s"
++/*0x0255*/	BYTE $0
++#line 749 "file9.s"
++/*0x0256*/	BYTE $0
++#line 41 "file0.s"
++/*0x0257*/	MOVL $0x1234567, AX
++#line 41 "file0.s"
++/*0x025c*/	BYTE $0
++#line 41 "file0.s"
++/*0x025d*/	BYTE $0
++#line 41 "file0.s"
++/*0x025e*/	BYTE $0
++#line 869 "file0.s"
++/*0x025f*/	BYTE $0
++#line 881 "file0.s"
++/*0x0260*/	MOVQ $0x123456789, AX
++#line 881 "file0.s"
++/*0x026a*/	MOVQ $0x123456789, AX
++	POPQ AX
++	POPQ AX
++	RET
++
++GLOBL funcdata0(SB), $16
++#line 1 "input"
++TEXT func1(SB),7,$40-648
++	FUNCDATA $1, funcdata1(SB)
++#line 1 "input"
++#line 1 "input"
++/*0x0004*/	BYTE $0
++#line 12 "file4.s"
++/*0x0005*/	MOVL $0x1234567, AX
++#line 12 "file4.s"
++/*0x000a*/	BYTE $0
++#line 12 "file4.s"
++/*0x000b*/	BYTE $0
++#line 12 "file4.s"
++/*0x000c*/	BYTE $0
++/*      */	PCDATA $2, $705
++#line 12 "file4.s"
++/*0x000d*/	MOVQ $0x123456789, AX
++#line 12 "file4.s"
++/*0x0017*/	BYTE $0
++#line 633 "file4.s"
++/*0x0018*/	MOVQ $0x123456789, AX
++#line 633 "file4.s"
++/*0x0022*/	MOVL $0x1234567, AX
++#line 633 "file4.s"
++/*0x0027*/	POPQ AX
++#line 633 "file4.s"
++/*0x0028*/	BYTE $0
++#line 633 "file4.s"
++/*0x0029*/	BYTE $0
++#line 633 "file4.s"
++/*0x002a*/	BYTE $0
++#line 633 "file4.s"
++/*0x002b*/	PUSHQ AX
++#line 633 "file4.s"
++/*0x002c*/	MOVL $0x1234567, AX
++#line 997 "file4.s"
++/*0x0031*/	BYTE $0
++#line 997 "file4.s"
++/*0x0032*/	BYTE $0
++#line 997 "file4.s"
++/*0x0033*/	BYTE $0
++#line 997 "file4.s"
++/*0x0034*/	BYTE $0
++#line 997 "file4.s"
++/*0x0035*/	POPQ AX
++#line 997 "file4.s"
++/*0x0036*/	BYTE $0
++#line 997 "file4.s"
++/*0x0037*/	BYTE $0
++#line 1 "file4.s"
++/*0x0038*/	MOVQ $0x123456789, AX
++#line 1 "file4.s"
++/*0x0042*/	MOVQ $0x123456789, AX
++#line 1 "file4.s"
++/*0x004c*/	MOVQ $0x123456789, AX
++#line 1 "file4.s"
++/*0x0056*/	MOVQ $0x123456789, AX
++#line 1 "file4.s"
++/*0x0060*/	BYTE $0
++#line 922 "file4.s"
++/*0x0061*/	BYTE $0
++#line 375 "file4.s"
++/*0x0062*/	MOVL $0x1234567, AX
++/*      */	PCDATA $1, $51
++#line 31 "file4.s"
++/*0x0067*/	MOVQ $0x123456789, AX
++#line 31 "file4.s"
++/*0x0071*/	BYTE $0
++#line 620 "file4.s"
++/*0x0072*/	MOVL $0x1234567, AX
++#line 620 "file4.s"
++/*0x0077*/	BYTE $0
++#line 695 "file4.s"
++/*0x0078*/	MOVL $0x1234567, AX
++#line 799 "file4.s"
++/*0x007d*/	MOVL $0x1234567, AX
++#line 41 "file4.s"
++/*0x0082*/	BYTE $0
++#line 795 "file4.s"
++/*0x0083*/	MOVL $0x1234567, AX
++#line 908 "file4.s"
++/*0x0088*/	BYTE $0
++#line 905 "file4.s"
++/*0x0089*/	BYTE $0
++#line 905 "file4.s"
++/*0x008a*/	BYTE $0
++#line 905 "file4.s"
++/*0x008b*/	BYTE $0
++#line 905 "file4.s"
++/*0x008c*/	BYTE $0
++#line 861 "file4.s"
++/*0x008d*/	MOVL $0x1234567, AX
++#line 861 "file4.s"
++/*0x0092*/	BYTE $0
++#line 861 "file4.s"
++/*0x0093*/	BYTE $0
++#line 861 "file4.s"
++/*0x0094*/	BYTE $0
++#line 861 "file4.s"
++/*0x0095*/	BYTE $0
++/*      */	PCDATA $1, $192
++#line 861 "file4.s"
++/*0x0096*/	MOVQ $0x123456789, AX
++/*      */	PCDATA $1, $60
++#line 861 "file4.s"
++/*0x00a0*/	MOVL $0x1234567, AX
++#line 861 "file4.s"
++/*0x00a5*/	BYTE $0
++#line 861 "file4.s"
++/*0x00a6*/	BYTE $0
++#line 56 "file6.s"
++/*0x00a7*/	MOVQ $0x123456789, AX
++#line 56 "file6.s"
++/*0x00b1*/	BYTE $0
++#line 56 "file6.s"
++/*0x00b2*/	BYTE $0
++#line 56 "file6.s"
++/*0x00b3*/	BYTE $0
++#line 204 "file6.s"
++/*0x00b4*/	BYTE $0
++#line 204 "file6.s"
++/*0x00b5*/	BYTE $0
++#line 204 "file6.s"
++/*0x00b6*/	BYTE $0
++#line 204 "file6.s"
++/*0x00b7*/	BYTE $0
++#line 979 "file6.s"
++/*0x00b8*/	MOVL $0x1234567, AX
++#line 979 "file6.s"
++/*0x00bd*/	BYTE $0
++#line 979 "file6.s"
++/*0x00be*/	BYTE $0
++#line 979 "file6.s"
++/*0x00bf*/	BYTE $0
++#line 58 "file6.s"
++/*0x00c0*/	MOVL $0x1234567, AX
++#line 238 "file6.s"
++/*0x00c5*/	MOVL $0x1234567, AX
++#line 238 "file6.s"
++/*0x00ca*/	BYTE $0
++#line 238 "file6.s"
++/*0x00cb*/	BYTE $0
++#line 699 "file2.s"
++/*0x00cc*/	MOVQ $0x123456789, AX
++#line 699 "file2.s"
++/*0x00d6*/	BYTE $0
++#line 699 "file2.s"
++/*0x00d7*/	BYTE $0
++#line 514 "file2.s"
++/*0x00d8*/	MOVL $0x1234567, AX
++#line 514 "file2.s"
++/*0x00dd*/	BYTE $0
++#line 514 "file2.s"
++/*0x00de*/	BYTE $0
++#line 108 "file2.s"
++/*0x00df*/	MOVQ $0x123456789, AX
++#line 108 "file2.s"
++/*0x00e9*/	MOVQ $0x123456789, AX
++#line 108 "file2.s"
++/*0x00f3*/	MOVL $0x1234567, AX
++#line 108 "file2.s"
++/*0x00f8*/	BYTE $0
++#line 108 "file2.s"
++/*0x00f9*/	BYTE $0
++#line 918 "file2.s"
++/*0x00fa*/	BYTE $0
++#line 918 "file2.s"
++/*0x00fb*/	BYTE $0
++#line 785 "file2.s"
++/*0x00fc*/	BYTE $0
++#line 3 "file5.s"
++/*0x00fd*/	BYTE $0
++#line 918 "file5.s"
++/*0x00fe*/	BYTE $0
++#line 918 "file5.s"
++/*0x00ff*/	BYTE $0
++#line 670 "file5.s"
++/*0x0100*/	MOVL $0x1234567, AX
++#line 670 "file5.s"
++/*0x0105*/	BYTE $0
++#line 720 "file5.s"
++/*0x0106*/	BYTE $0
++#line 384 "file5.s"
++/*0x0107*/	MOVQ $0x123456789, AX
++#line 384 "file5.s"
++/*0x0111*/	MOVQ $0x123456789, AX
++#line 384 "file5.s"
++/*0x011b*/	MOVQ $0x123456789, AX
++#line 384 "file5.s"
++/*0x0125*/	BYTE $0
++#line 384 "file5.s"
++/*0x0126*/	BYTE $0
++#line 263 "file5.s"
++/*0x0127*/	BYTE $0
++#line 750 "file5.s"
++/*0x0128*/	MOVL $0x1234567, AX
++#line 750 "file5.s"
++/*0x012d*/	BYTE $0
++#line 679 "file5.s"
++/*0x012e*/	MOVL $0x1234567, AX
++#line 679 "file5.s"
++/*0x0133*/	BYTE $0
++#line 679 "file5.s"
++/*0x0134*/	BYTE $0
++#line 679 "file5.s"
++/*0x0135*/	BYTE $0
++#line 679 "file5.s"
++/*0x0136*/	POPQ AX
++#line 171 "file5.s"
++/*0x0137*/	MOVL $0x1234567, AX
++#line 171 "file5.s"
++/*0x013c*/	BYTE $0
++#line 34 "file2.s"
++/*0x013d*/	BYTE $0
++#line 34 "file2.s"
++/*0x013e*/	BYTE $0
++#line 34 "file2.s"
++/*0x013f*/	BYTE $0
++#line 732 "file2.s"
++/*0x0140*/	BYTE $0
++#line 732 "file2.s"
++/*0x0141*/	PUSHQ AX
++#line 485 "file2.s"
++/*0x0142*/	BYTE $0
++#line 485 "file2.s"
++/*0x0143*/	BYTE $0
++#line 485 "file2.s"
++/*0x0144*/	BYTE $0
++#line 222 "file2.s"
++/*0x0145*/	BYTE $0
++#line 222 "file2.s"
++/*0x0146*/	BYTE $0
++/*      */	PCDATA $1, $462
++#line 222 "file2.s"
++/*0x0147*/	MOVQ $0x123456789, AX
++#line 222 "file2.s"
++/*0x0151*/	MOVL $0x1234567, AX
++#line 222 "file2.s"
++/*0x0156*/	BYTE $0
++#line 677 "file2.s"
++/*0x0157*/	BYTE $0
++#line 117 "file2.s"
++/*0x0158*/	MOVL $0x1234567, AX
++#line 117 "file2.s"
++/*0x015d*/	BYTE $0
++#line 117 "file2.s"
++/*0x015e*/	BYTE $0
++#line 361 "file2.s"
++/*0x015f*/	MOVL $0x1234567, AX
++#line 590 "file2.s"
++/*0x0164*/	BYTE $0
++#line 590 "file2.s"
++/*0x0165*/	BYTE $0
++#line 58 "file2.s"
++/*0x0166*/	MOVL $0x1234567, AX
++#line 58 "file2.s"
++/*0x016b*/	BYTE $0
++#line 58 "file2.s"
++/*0x016c*/	BYTE $0
++#line 58 "file2.s"
++/*0x016d*/	BYTE $0
++#line 58 "file2.s"
++/*0x016e*/	BYTE $0
++#line 983 "file2.s"
++/*0x016f*/	BYTE $0
++#line 983 "file2.s"
++/*0x0170*/	BYTE $0
++#line 983 "file2.s"
++/*0x0171*/	BYTE $0
++#line 983 "file2.s"
++/*0x0172*/	BYTE $0
++#line 727 "file2.s"
++/*0x0173*/	MOVL $0x1234567, AX
++#line 450 "file2.s"
++/*0x0178*/	BYTE $0
++#line 450 "file2.s"
++/*0x0179*/	BYTE $0
++#line 450 "file2.s"
++/*0x017a*/	BYTE $0
++#line 450 "file2.s"
++/*0x017b*/	BYTE $0
++#line 334 "file2.s"
++/*0x017c*/	BYTE $0
++#line 334 "file2.s"
++/*0x017d*/	BYTE $0
++#line 334 "file2.s"
++/*0x017e*/	BYTE $0
++#line 334 "file2.s"
++/*0x017f*/	BYTE $0
++#line 465 "file2.s"
++/*0x0180*/	MOVL $0x1234567, AX
++/*      */	PCDATA $1, $518
++#line 465 "file2.s"
++/*0x0185*/	MOVL $0x1234567, AX
++#line 465 "file2.s"
++/*0x018a*/	BYTE $0
++#line 465 "file2.s"
++/*0x018b*/	BYTE $0
++#line 465 "file2.s"
++/*0x018c*/	BYTE $0
++#line 465 "file2.s"
++/*0x018d*/	BYTE $0
++#line 682 "file2.s"
++/*0x018e*/	MOVL $0x1234567, AX
++#line 682 "file2.s"
++/*0x0193*/	BYTE $0
++#line 682 "file2.s"
++/*0x0194*/	BYTE $0
++#line 846 "file2.s"
++/*0x0195*/	MOVQ $0x123456789, AX
++#line 846 "file2.s"
++/*0x019f*/	BYTE $0
++#line 846 "file2.s"
++/*0x01a0*/	BYTE $0
++#line 846 "file2.s"
++/*0x01a1*/	POPQ AX
++#line 846 "file2.s"
++/*0x01a2*/	BYTE $0
++#line 846 "file2.s"
++/*0x01a3*/	BYTE $0
++#line 49 "file2.s"
++/*0x01a4*/	BYTE $0
++#line 49 "file2.s"
++/*0x01a5*/	BYTE $0
++#line 49 "file2.s"
++/*0x01a6*/	BYTE $0
++#line 726 "file2.s"
++/*0x01a7*/	MOVQ $0x123456789, AX
++#line 726 "file2.s"
++/*0x01b1*/	MOVL $0x1234567, AX
++#line 726 "file2.s"
++/*0x01b6*/	BYTE $0
++#line 726 "file2.s"
++/*0x01b7*/	BYTE $0
++#line 726 "file2.s"
++/*0x01b8*/	BYTE $0
++#line 726 "file2.s"
++/*0x01b9*/	PUSHQ AX
++#line 726 "file2.s"
++/*0x01ba*/	BYTE $0
++#line 726 "file2.s"
++/*0x01bb*/	BYTE $0
++#line 726 "file2.s"
++/*0x01bc*/	BYTE $0
++#line 726 "file2.s"
++/*0x01bd*/	BYTE $0
++#line 13 "file1.s"
++/*0x01be*/	BYTE $0
++#line 13 "file1.s"
++/*0x01bf*/	BYTE $0
++#line 13 "file1.s"
++/*0x01c0*/	BYTE $0
++#line 827 "file1.s"
++/*0x01c1*/	MOVL $0x1234567, AX
++#line 827 "file1.s"
++/*0x01c6*/	BYTE $0
++#line 827 "file1.s"
++/*0x01c7*/	BYTE $0
++#line 827 "file1.s"
++/*0x01c8*/	BYTE $0
++#line 827 "file1.s"
++/*0x01c9*/	BYTE $0
++#line 783 "file1.s"
++/*0x01ca*/	BYTE $0
++#line 783 "file1.s"
++/*0x01cb*/	BYTE $0
++#line 783 "file1.s"
++/*0x01cc*/	BYTE $0
++#line 783 "file1.s"
++/*0x01cd*/	BYTE $0
++#line 367 "file1.s"
++/*0x01ce*/	MOVQ $0x123456789, AX
++#line 367 "file1.s"
++/*0x01d8*/	MOVL $0x1234567, AX
++#line 367 "file1.s"
++/*0x01dd*/	BYTE $0
++#line 367 "file1.s"
++/*0x01de*/	BYTE $0
++#line 367 "file1.s"
++/*0x01df*/	BYTE $0
++#line 367 "file1.s"
++/*0x01e0*/	BYTE $0
++#line 581 "file1.s"
++/*0x01e1*/	BYTE $0
++#line 581 "file1.s"
++/*0x01e2*/	BYTE $0
++#line 581 "file1.s"
++/*0x01e3*/	BYTE $0
++#line 638 "file1.s"
++/*0x01e4*/	MOVQ $0x123456789, AX
++#line 638 "file1.s"
++/*0x01ee*/	MOVL $0x1234567, AX
++#line 638 "file1.s"
++/*0x01f3*/	BYTE $0
++#line 638 "file1.s"
++/*0x01f4*/	BYTE $0
++#line 638 "file1.s"
++/*0x01f5*/	BYTE $0
++#line 359 "file1.s"
++/*0x01f6*/	BYTE $0
++#line 449 "file1.s"
++/*0x01f7*/	BYTE $0
++#line 449 "file1.s"
++/*0x01f8*/	BYTE $0
++#line 449 "file1.s"
++/*0x01f9*/	BYTE $0
++#line 298 "file1.s"
++/*0x01fa*/	BYTE $0
++#line 298 "file1.s"
++/*0x01fb*/	BYTE $0
++#line 257 "file1.s"
++/*0x01fc*/	BYTE $0
++#line 257 "file1.s"
++/*0x01fd*/	BYTE $0
++#line 257 "file1.s"
++/*0x01fe*/	BYTE $0
++#line 512 "file1.s"
++/*0x01ff*/	MOVL $0x1234567, AX
++#line 512 "file1.s"
++/*0x0204*/	BYTE $0
++#line 512 "file1.s"
++/*0x0205*/	BYTE $0
++#line 617 "file1.s"
++/*0x0206*/	MOVL $0x1234567, AX
++#line 478 "file1.s"
++/*0x020b*/	BYTE $0
++/*      */	PCDATA $2, $351
++#line 478 "file1.s"
++/*0x020c*/	BYTE $0
++#line 958 "file1.s"
++/*0x020d*/	BYTE $0
++#line 958 "file1.s"
++/*0x020e*/	BYTE $0
++#line 958 "file1.s"
++/*0x020f*/	BYTE $0
++#line 958 "file1.s"
++/*0x0210*/	BYTE $0
++#line 371 "file1.s"
++/*0x0211*/	MOVQ $0x123456789, AX
++#line 371 "file1.s"
++/*0x021b*/	BYTE $0
++#line 371 "file1.s"
++/*0x021c*/	BYTE $0
++#line 56 "file3.s"
++/*0x021d*/	MOVL $0x1234567, AX
++#line 56 "file3.s"
++/*0x0222*/	BYTE $0
++#line 56 "file3.s"
++/*0x0223*/	BYTE $0
++#line 56 "file9.s"
++/*0x0224*/	MOVQ $0x123456789, AX
++#line 56 "file9.s"
++/*0x022e*/	BYTE $0
++#line 56 "file9.s"
++/*0x022f*/	BYTE $0
++#line 56 "file9.s"
++/*0x0230*/	BYTE $0
++#line 56 "file9.s"
++/*0x0231*/	BYTE $0
++#line 684 "file9.s"
++/*0x0232*/	MOVQ $0x123456789, AX
++#line 684 "file9.s"
++/*0x023c*/	BYTE $0
++#line 684 "file9.s"
++/*0x023d*/	POPQ AX
++#line 407 "file9.s"
++/*0x023e*/	MOVL $0x1234567, AX
++#line 407 "file9.s"
++/*0x0243*/	BYTE $0
++	PUSHQ AX
++	PUSHQ AX
++	RET
++
++GLOBL funcdata1(SB), $16
++#line 1 "input"
++TEXT func2(SB),7,$40-688
++	FUNCDATA $1, funcdata2(SB)
++#line 1 "input"
++#line 1 "input"
++/*0x0004*/	BYTE $0
++#line 860 "input"
++/*0x0005*/	BYTE $0
++#line 860 "input"
++/*0x0006*/	BYTE $0
++#line 860 "input"
++/*0x0007*/	BYTE $0
++#line 860 "input"
++/*0x0008*/	BYTE $0
++#line 85 "input"
++/*0x0009*/	BYTE $0
++#line 85 "input"
++/*0x000a*/	BYTE $0
++#line 355 "input"
++/*0x000b*/	MOVQ $0x123456789, AX
++#line 355 "input"
++/*0x0015*/	MOVL $0x1234567, AX
++#line 355 "input"
++/*0x001a*/	BYTE $0
++#line 355 "input"
++/*0x001b*/	BYTE $0
++#line 355 "input"
++/*0x001c*/	BYTE $0
++#line 840 "input"
++/*0x001d*/	MOVL $0x1234567, AX
++#line 840 "input"
++/*0x0022*/	BYTE $0
++#line 294 "input"
++/*0x0023*/	MOVQ $0x123456789, AX
++#line 294 "input"
++/*0x002d*/	MOVQ $0x123456789, AX
++#line 294 "input"
++/*0x0037*/	MOVQ $0x123456789, AX
++#line 294 "input"
++/*0x0041*/	BYTE $0
++#line 294 "input"
++/*0x0042*/	BYTE $0
++#line 294 "input"
++/*0x0043*/	BYTE $0
++#line 294 "input"
++/*0x0044*/	BYTE $0
++/*      */	PCDATA $1, $385
++#line 294 "input"
++/*0x0045*/	BYTE $0
++#line 294 "input"
++/*0x0046*/	BYTE $0
++#line 294 "input"
++/*0x0047*/	BYTE $0
++#line 81 "file9.s"
++/*0x0048*/	MOVL $0x1234567, AX
++#line 81 "file9.s"
++/*0x004d*/	BYTE $0
++#line 81 "file9.s"
++/*0x004e*/	BYTE $0
++#line 81 "file9.s"
++/*0x004f*/	POPQ AX
++#line 81 "file9.s"
++/*0x0050*/	MOVL $0x1234567, AX
++#line 81 "file9.s"
++/*0x0055*/	BYTE $0
++/*      */	PCDATA $1, $701
++#line 81 "file9.s"
++/*0x0056*/	MOVL $0x1234567, AX
++#line 81 "file9.s"
++/*0x005b*/	BYTE $0
++#line 81 "file9.s"
++/*0x005c*/	BYTE $0
++#line 81 "file9.s"
++/*0x005d*/	BYTE $0
++#line 81 "file9.s"
++/*0x005e*/	BYTE $0
++#line 290 "file9.s"
++/*0x005f*/	BYTE $0
++#line 290 "file9.s"
++/*0x0060*/	BYTE $0
++#line 290 "file9.s"
++/*0x0061*/	BYTE $0
++#line 197 "file9.s"
++/*0x0062*/	MOVL $0x1234567, AX
++#line 197 "file9.s"
++/*0x0067*/	BYTE $0
++#line 608 "file9.s"
++/*0x0068*/	MOVQ $0x123456789, AX
++#line 608 "file9.s"
++/*0x0072*/	MOVQ $0x123456789, AX
++#line 608 "file9.s"
++/*0x007c*/	BYTE $0
++/*      */	PCDATA $1, $562
++#line 608 "file9.s"
++/*0x007d*/	BYTE $0
++#line 608 "file9.s"
++/*0x007e*/	BYTE $0
++#line 189 "file9.s"
++/*0x007f*/	MOVL $0x1234567, AX
++#line 189 "file9.s"
++/*0x0084*/	BYTE $0
++#line 189 "file9.s"
++/*0x0085*/	BYTE $0
++#line 189 "file9.s"
++/*0x0086*/	BYTE $0
++#line 189 "file9.s"
++/*0x0087*/	BYTE $0
++#line 472 "file9.s"
++/*0x0088*/	MOVL $0x1234567, AX
++#line 472 "file9.s"
++/*0x008d*/	BYTE $0
++#line 472 "file9.s"
++/*0x008e*/	BYTE $0
++#line 472 "file9.s"
++/*0x008f*/	PUSHQ AX
++#line 472 "file9.s"
++/*0x0090*/	MOVQ $0x123456789, AX
++#line 472 "file9.s"
++/*0x009a*/	MOVL $0x1234567, AX
++#line 472 "file9.s"
++/*0x009f*/	BYTE $0
++#line 472 "file9.s"
++/*0x00a0*/	BYTE $0
++#line 472 "file9.s"
++/*0x00a1*/	BYTE $0
++#line 472 "file9.s"
++/*0x00a2*/	BYTE $0
++#line 148 "file9.s"
++/*0x00a3*/	MOVQ $0x123456789, AX
++#line 148 "file9.s"
++/*0x00ad*/	BYTE $0
++#line 148 "file9.s"
++/*0x00ae*/	BYTE $0
++#line 148 "file9.s"
++/*0x00af*/	BYTE $0
++#line 148 "file9.s"
++/*0x00b0*/	BYTE $0
++#line 562 "file9.s"
++/*0x00b1*/	MOVL $0x1234567, AX
++#line 562 "file9.s"
++/*0x00b6*/	BYTE $0
++#line 562 "file9.s"
++/*0x00b7*/	PUSHQ AX
++#line 562 "file9.s"
++/*0x00b8*/	BYTE $0
++#line 532 "file9.s"
++/*0x00b9*/	MOVQ $0x123456789, AX
++#line 532 "file9.s"
++/*0x00c3*/	MOVQ $0x123456789, AX
++#line 282 "file9.s"
++/*0x00cd*/	BYTE $0
++#line 282 "file9.s"
++/*0x00ce*/	BYTE $0
++#line 282 "file9.s"
++/*0x00cf*/	BYTE $0
++/*      */	PCDATA $2, $861
++#line 282 "file9.s"
++/*0x00d0*/	BYTE $0
++#line 282 "file9.s"
++/*0x00d1*/	BYTE $0
++/*      */	PCDATA $2, $310
++#line 282 "file9.s"
++/*0x00d2*/	BYTE $0
++#line 416 "file9.s"
++/*0x00d3*/	MOVQ $0x123456789, AX
++#line 416 "file9.s"
++/*0x00dd*/	MOVL $0x1234567, AX
++#line 780 "file9.s"
++/*0x00e2*/	BYTE $0
++#line 780 "file9.s"
++/*0x00e3*/	BYTE $0
++#line 765 "file9.s"
++/*0x00e4*/	MOVL $0x1234567, AX
++#line 523 "file9.s"
++/*0x00e9*/	BYTE $0
++#line 523 "file9.s"
++/*0x00ea*/	BYTE $0
++#line 523 "file9.s"
++/*0x00eb*/	BYTE $0
++#line 733 "file9.s"
++/*0x00ec*/	MOVQ $0x123456789, AX
++#line 378 "file9.s"
++/*0x00f6*/	BYTE $0
++#line 378 "file9.s"
++/*0x00f7*/	BYTE $0
++#line 378 "file9.s"
++/*0x00f8*/	BYTE $0
++#line 378 "file9.s"
++/*0x00f9*/	BYTE $0
++#line 540 "file9.s"
++/*0x00fa*/	BYTE $0
++#line 540 "file9.s"
++/*0x00fb*/	BYTE $0
++#line 57 "file9.s"
++/*0x00fc*/	BYTE $0
++#line 57 "file9.s"
++/*0x00fd*/	BYTE $0
++#line 57 "file9.s"
++/*0x00fe*/	BYTE $0
++#line 417 "file9.s"
++/*0x00ff*/	BYTE $0
++/*      */	PCDATA $1, $932
++#line 417 "file9.s"
++/*0x0100*/	BYTE $0
++#line 417 "file9.s"
++/*0x0101*/	BYTE $0
++#line 417 "file9.s"
++/*0x0102*/	BYTE $0
++#line 417 "file9.s"
++/*0x0103*/	BYTE $0
++#line 713 "file9.s"
++/*0x0104*/	MOVL $0x1234567, AX
++#line 610 "file0.s"
++/*0x0109*/	MOVQ $0x123456789, AX
++#line 610 "file0.s"
++/*0x0113*/	MOVL $0x1234567, AX
++#line 610 "file0.s"
++/*0x0118*/	BYTE $0
++#line 787 "file0.s"
++/*0x0119*/	MOVQ $0x123456789, AX
++#line 829 "file0.s"
++/*0x0123*/	BYTE $0
++#line 829 "file0.s"
++/*0x0124*/	BYTE $0
++#line 829 "file0.s"
++/*0x0125*/	BYTE $0
++#line 849 "file0.s"
++/*0x0126*/	BYTE $0
++#line 849 "file0.s"
++/*0x0127*/	BYTE $0
++#line 849 "file0.s"
++/*0x0128*/	BYTE $0
++/*      */	PCDATA $2, $356
++#line 849 "file0.s"
++/*0x0129*/	BYTE $0
++#line 849 "file0.s"
++/*0x012a*/	BYTE $0
++#line 88 "file0.s"
++/*0x012b*/	MOVL $0x1234567, AX
++#line 88 "file0.s"
++/*0x0130*/	BYTE $0
++#line 88 "file0.s"
++/*0x0131*/	BYTE $0
++#line 88 "file0.s"
++/*0x0132*/	BYTE $0
++#line 684 "file0.s"
++/*0x0133*/	BYTE $0
++#line 684 "file0.s"
++/*0x0134*/	BYTE $0
++#line 684 "file0.s"
++/*0x0135*/	BYTE $0
++#line 684 "file0.s"
++/*0x0136*/	BYTE $0
++#line 238 "file0.s"
++/*0x0137*/	BYTE $0
++#line 238 "file0.s"
++/*0x0138*/	BYTE $0
++#line 238 "file0.s"
++/*0x0139*/	PUSHQ AX
++#line 238 "file0.s"
++/*0x013a*/	BYTE $0
++#line 238 "file0.s"
++/*0x013b*/	BYTE $0
++#line 603 "file0.s"
++/*0x013c*/	BYTE $0
++#line 981 "file0.s"
++/*0x013d*/	BYTE $0
++#line 981 "file0.s"
++/*0x013e*/	POPQ AX
++#line 616 "file0.s"
++/*0x013f*/	BYTE $0
++#line 616 "file0.s"
++/*0x0140*/	BYTE $0
++#line 616 "file0.s"
++/*0x0141*/	BYTE $0
++#line 616 "file0.s"
++/*0x0142*/	BYTE $0
++#line 716 "file0.s"
++/*0x0143*/	MOVL $0x1234567, AX
++#line 716 "file0.s"
++/*0x0148*/	BYTE $0
++#line 716 "file0.s"
++/*0x0149*/	BYTE $0
++#line 34 "file0.s"
++/*0x014a*/	BYTE $0
++#line 34 "file0.s"
++/*0x014b*/	BYTE $0
++#line 34 "file0.s"
++/*0x014c*/	BYTE $0
++#line 90 "file0.s"
++/*0x014d*/	MOVL $0x1234567, AX
++#line 316 "file0.s"
++/*0x0152*/	MOVQ $0x123456789, AX
++#line 230 "file0.s"
++/*0x015c*/	MOVQ $0x123456789, AX
++#line 799 "file0.s"
++/*0x0166*/	MOVQ $0x123456789, AX
++#line 799 "file0.s"
++/*0x0170*/	BYTE $0
++#line 799 "file0.s"
++/*0x0171*/	BYTE $0
++/*      */	PCDATA $1, $247
++#line 799 "file0.s"
++/*0x0172*/	BYTE $0
++#line 799 "file0.s"
++/*0x0173*/	BYTE $0
++#line 799 "file0.s"
++/*0x0174*/	BYTE $0
++#line 655 "file0.s"
++/*0x0175*/	MOVL $0x1234567, AX
++#line 655 "file0.s"
++/*0x017a*/	BYTE $0
++#line 551 "file0.s"
++/*0x017b*/	BYTE $0
++#line 551 "file0.s"
++/*0x017c*/	BYTE $0
++#line 271 "file0.s"
++/*0x017d*/	MOVQ $0x123456789, AX
++#line 271 "file0.s"
++/*0x0187*/	MOVQ $0x123456789, AX
++#line 271 "file0.s"
++/*0x0191*/	MOVL $0x1234567, AX
++#line 271 "file0.s"
++/*0x0196*/	BYTE $0
++#line 271 "file0.s"
++/*0x0197*/	BYTE $0
++#line 271 "file0.s"
++/*0x0198*/	BYTE $0
++#line 233 "file0.s"
++/*0x0199*/	MOVL $0x1234567, AX
++#line 233 "file0.s"
++/*0x019e*/	BYTE $0
++#line 233 "file0.s"
++/*0x019f*/	BYTE $0
++#line 233 "file0.s"
++/*0x01a0*/	BYTE $0
++#line 233 "file0.s"
++/*0x01a1*/	BYTE $0
++#line 738 "file0.s"
++/*0x01a2*/	MOVL $0x1234567, AX
++#line 738 "file0.s"
++/*0x01a7*/	BYTE $0
++#line 800 "file0.s"
++/*0x01a8*/	BYTE $0
++#line 800 "file0.s"
++/*0x01a9*/	BYTE $0
++#line 646 "file0.s"
++/*0x01aa*/	MOVQ $0x123456789, AX
++#line 646 "file0.s"
++/*0x01b4*/	BYTE $0
++#line 646 "file0.s"
++/*0x01b5*/	BYTE $0
++#line 646 "file0.s"
++/*0x01b6*/	BYTE $0
++#line 709 "file0.s"
++/*0x01b7*/	BYTE $0
++#line 709 "file0.s"
++/*0x01b8*/	BYTE $0
++#line 709 "file0.s"
++/*0x01b9*/	BYTE $0
++#line 709 "file0.s"
++/*0x01ba*/	BYTE $0
++#line 296 "file0.s"
++/*0x01bb*/	BYTE $0
++#line 296 "file0.s"
++/*0x01bc*/	BYTE $0
++#line 296 "file0.s"
++/*0x01bd*/	BYTE $0
++#line 71 "file0.s"
++/*0x01be*/	BYTE $0
++#line 71 "file0.s"
++/*0x01bf*/	BYTE $0
++#line 71 "file0.s"
++/*0x01c0*/	BYTE $0
++#line 7 "file2.s"
++/*0x01c1*/	BYTE $0
++#line 747 "file2.s"
++/*0x01c2*/	BYTE $0
++#line 177 "file2.s"
++/*0x01c3*/	MOVQ $0x123456789, AX
++#line 177 "file2.s"
++/*0x01cd*/	MOVQ $0x123456789, AX
++#line 177 "file2.s"
++/*0x01d7*/	MOVL $0x1234567, AX
++#line 177 "file2.s"
++/*0x01dc*/	BYTE $0
++#line 177 "file2.s"
++/*0x01dd*/	BYTE $0
++#line 177 "file2.s"
++/*0x01de*/	BYTE $0
++#line 72 "file2.s"
++/*0x01df*/	BYTE $0
++#line 215 "file2.s"
++/*0x01e0*/	MOVL $0x1234567, AX
++#line 215 "file2.s"
++/*0x01e5*/	BYTE $0
++#line 215 "file2.s"
++/*0x01e6*/	BYTE $0
++#line 215 "file2.s"
++/*0x01e7*/	BYTE $0
++#line 946 "file2.s"
++/*0x01e8*/	BYTE $0
++#line 946 "file2.s"
++/*0x01e9*/	BYTE $0
++#line 946 "file2.s"
++/*0x01ea*/	BYTE $0
++#line 946 "file2.s"
++/*0x01eb*/	BYTE $0
++#line 263 "file2.s"
++/*0x01ec*/	MOVL $0x1234567, AX
++#line 263 "file2.s"
++/*0x01f1*/	BYTE $0
++#line 897 "file2.s"
++/*0x01f2*/	MOVQ $0x123456789, AX
++#line 897 "file2.s"
++/*0x01fc*/	MOVQ $0x123456789, AX
++#line 897 "file2.s"
++/*0x0206*/	BYTE $0
++#line 897 "file2.s"
++/*0x0207*/	BYTE $0
++#line 897 "file2.s"
++/*0x0208*/	BYTE $0
++#line 229 "file2.s"
++/*0x0209*/	BYTE $0
++#line 229 "file2.s"
++/*0x020a*/	BYTE $0
++#line 229 "file2.s"
++/*0x020b*/	BYTE $0
++#line 229 "file2.s"
++/*0x020c*/	BYTE $0
++/*      */	PCDATA $1, $7
++#line 229 "file2.s"
++/*0x020d*/	MOVL $0x1234567, AX
++#line 229 "file2.s"
++/*0x0212*/	BYTE $0
++#line 353 "file2.s"
++/*0x0213*/	BYTE $0
++#line 353 "file2.s"
++/*0x0214*/	BYTE $0
++#line 353 "file2.s"
++/*0x0215*/	BYTE $0
++#line 353 "file2.s"
++/*0x0216*/	BYTE $0
++#line 852 "file2.s"
++/*0x0217*/	BYTE $0
++#line 852 "file2.s"
++/*0x0218*/	BYTE $0
++#line 852 "file2.s"
++/*0x0219*/	BYTE $0
++#line 852 "file2.s"
++/*0x021a*/	BYTE $0
++#line 852 "file2.s"
++/*0x021b*/	PUSHQ AX
++#line 852 "file2.s"
++/*0x021c*/	BYTE $0
++#line 852 "file2.s"
++/*0x021d*/	BYTE $0
++#line 852 "file2.s"
++/*0x021e*/	BYTE $0
++#line 904 "file2.s"
++/*0x021f*/	MOVQ $0x123456789, AX
++#line 904 "file2.s"
++/*0x0229*/	BYTE $0
++#line 904 "file2.s"
++/*0x022a*/	BYTE $0
++#line 882 "file2.s"
++/*0x022b*/	BYTE $0
++#line 905 "file2.s"
++/*0x022c*/	BYTE $0
++#line 410 "file2.s"
++/*0x022d*/	MOVQ $0x123456789, AX
++#line 410 "file2.s"
++/*0x0237*/	BYTE $0
++#line 410 "file2.s"
++/*0x0238*/	BYTE $0
++#line 410 "file2.s"
++/*0x0239*/	POPQ AX
++#line 410 "file2.s"
++/*0x023a*/	BYTE $0
++#line 410 "file2.s"
++/*0x023b*/	BYTE $0
++#line 410 "file2.s"
++/*0x023c*/	BYTE $0
++/*      */	PCDATA $2, $173
++#line 410 "file2.s"
++/*0x023d*/	MOVL $0x1234567, AX
++#line 410 "file2.s"
++/*0x0242*/	BYTE $0
++/*      */	PCDATA $1, $396
++#line 410 "file2.s"
++/*0x0243*/	BYTE $0
++#line 410 "file2.s"
++/*0x0244*/	BYTE $0
++#line 666 "file2.s"
++/*0x0245*/	BYTE $0
++#line 129 "file2.s"
++/*0x0246*/	MOVQ $0x123456789, AX
++#line 129 "file2.s"
++/*0x0250*/	BYTE $0
++#line 391 "file2.s"
++/*0x0251*/	BYTE $0
++#line 696 "file2.s"
++/*0x0252*/	MOVL $0x1234567, AX
++#line 940 "file2.s"
++/*0x0257*/	BYTE $0
++#line 940 "file2.s"
++/*0x0258*/	BYTE $0
++#line 606 "file2.s"
++/*0x0259*/	MOVL $0x1234567, AX
++#line 606 "file2.s"
++/*0x025e*/	BYTE $0
++#line 648 "file2.s"
++/*0x025f*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x0269*/	BYTE $0
++#line 648 "file2.s"
++/*0x026a*/	BYTE $0
++/*      */	PCDATA $2, $84
++#line 648 "file2.s"
++/*0x026b*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x0275*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x027f*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x0289*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x0293*/	MOVQ $0x123456789, AX
++#line 648 "file2.s"
++/*0x029d*/	MOVL $0x1234567, AX
++#line 648 "file2.s"
++/*0x02a2*/	PUSHQ AX
++#line 648 "file2.s"
++/*0x02a3*/	MOVL $0x1234567, AX
++#line 648 "file2.s"
++/*0x02a8*/	BYTE $0
++#line 648 "file2.s"
++/*0x02a9*/	BYTE $0
++#line 648 "file2.s"
++/*0x02aa*/	BYTE $0
++#line 648 "file2.s"
++/*0x02ab*/	BYTE $0
++#line 449 "file2.s"
++/*0x02ac*/	MOVQ $0x123456789, AX
++#line 449 "file2.s"
++/*0x02b6*/	MOVL $0x1234567, AX
++#line 284 "file2.s"
++/*0x02bb*/	BYTE $0
++#line 284 "file2.s"
++/*0x02bc*/	BYTE $0
++#line 284 "file2.s"
++/*0x02bd*/	BYTE $0
++#line 284 "file2.s"
++/*0x02be*/	BYTE $0
++#line 26 "file2.s"
++/*0x02bf*/	MOVQ $0x123456789, AX
++#line 26 "file2.s"
++/*0x02c9*/	MOVL $0x1234567, AX
++#line 26 "file2.s"
++/*0x02ce*/	BYTE $0
++#line 26 "file2.s"
++/*0x02cf*/	BYTE $0
++#line 26 "file2.s"
++/*0x02d0*/	BYTE $0
++#line 605 "file2.s"
++/*0x02d1*/	MOVL $0x1234567, AX
++#line 605 "file2.s"
++/*0x02d6*/	BYTE $0
++#line 605 "file2.s"
++/*0x02d7*/	BYTE $0
++#line 605 "file2.s"
++/*0x02d8*/	BYTE $0
++#line 593 "file2.s"
++/*0x02d9*/	MOVL $0x1234567, AX
++#line 541 "file2.s"
++/*0x02de*/	MOVL $0x1234567, AX
++#line 541 "file2.s"
++/*0x02e3*/	BYTE $0
++#line 541 "file2.s"
++/*0x02e4*/	BYTE $0
++#line 181 "file2.s"
++/*0x02e5*/	MOVQ $0x123456789, AX
++#line 181 "file2.s"
++/*0x02ef*/	BYTE $0
++#line 907 "file2.s"
++/*0x02f0*/	MOVQ $0x123456789, AX
++#line 704 "file2.s"
++/*0x02fa*/	MOVQ $0x123456789, AX
++#line 704 "file2.s"
++/*0x0304*/	MOVQ $0x123456789, AX
++#line 704 "file2.s"
++/*0x030e*/	MOVL $0x1234567, AX
++#line 704 "file2.s"
++/*0x0313*/	BYTE $0
++#line 704 "file2.s"
++/*0x0314*/	BYTE $0
++#line 704 "file2.s"
++/*0x0315*/	BYTE $0
++#line 704 "file2.s"
++/*0x0316*/	BYTE $0
++#line 859 "file2.s"
++/*0x0317*/	MOVL $0x1234567, AX
++#line 407 "file2.s"
++/*0x031c*/	BYTE $0
++#line 407 "file2.s"
++/*0x031d*/	BYTE $0
++/*      */	PCDATA $2, $569
++#line 407 "file2.s"
++/*0x031e*/	MOVL $0x1234567, AX
++#line 407 "file2.s"
++/*0x0323*/	BYTE $0
++#line 407 "file2.s"
++/*0x0324*/	BYTE $0
++#line 407 "file2.s"
++/*0x0325*/	BYTE $0
++/*      */	PCDATA $1, $937
++#line 407 "file2.s"
++/*0x0326*/	MOVL $0x1234567, AX
++#line 407 "file2.s"
++/*0x032b*/	BYTE $0
++#line 774 "file2.s"
++/*0x032c*/	MOVQ $0x123456789, AX
++#line 774 "file2.s"
++/*0x0336*/	BYTE $0
++#line 547 "file2.s"
++/*0x0337*/	BYTE $0
++#line 547 "file2.s"
++/*0x0338*/	BYTE $0
++#line 547 "file2.s"
++/*0x0339*/	BYTE $0
++#line 547 "file2.s"
++/*0x033a*/	PUSHQ AX
++#line 547 "file2.s"
++/*0x033b*/	MOVL $0x1234567, AX
++#line 427 "file2.s"
++/*0x0340*/	MOVL $0x1234567, AX
++/*      */	PCDATA $1, $462
++#line 427 "file2.s"
++/*0x0345*/	MOVQ $0x123456789, AX
++#line 427 "file2.s"
++/*0x034f*/	MOVL $0x1234567, AX
++#line 427 "file2.s"
++/*0x0354*/	BYTE $0
++#line 427 "file2.s"
++/*0x0355*/	BYTE $0
++#line 427 "file2.s"
++/*0x0356*/	BYTE $0
++#line 427 "file2.s"
++/*0x0357*/	BYTE $0
++/*      */	PCDATA $2, $303
++#line 427 "file2.s"
++/*0x0358*/	MOVQ $0x123456789, AX
++#line 427 "file2.s"
++/*0x0362*/	BYTE $0
++#line 427 "file2.s"
++/*0x0363*/	BYTE $0
++#line 708 "file2.s"
++/*0x0364*/	BYTE $0
++#line 708 "file2.s"
++/*0x0365*/	BYTE $0
++#line 708 "file2.s"
++/*0x0366*/	BYTE $0
++#line 708 "file2.s"
++/*0x0367*/	BYTE $0
++#line 218 "file2.s"
++/*0x0368*/	MOVL $0x1234567, AX
++#line 44 "file2.s"
++/*0x036d*/	BYTE $0
++#line 915 "file2.s"
++/*0x036e*/	BYTE $0
++#line 915 "file2.s"
++/*0x036f*/	BYTE $0
++#line 915 "file2.s"
++/*0x0370*/	BYTE $0
++#line 915 "file2.s"
++/*0x0371*/	BYTE $0
++#line 122 "file2.s"
++/*0x0372*/	MOVQ $0x123456789, AX
++#line 122 "file2.s"
++/*0x037c*/	MOVL $0x1234567, AX
++#line 122 "file2.s"
++/*0x0381*/	BYTE $0
++#line 122 "file2.s"
++/*0x0382*/	BYTE $0
++#line 266 "file2.s"
++/*0x0383*/	BYTE $0
++#line 266 "file2.s"
++/*0x0384*/	BYTE $0
++#line 368 "file2.s"
++/*0x0385*/	BYTE $0
++#line 368 "file2.s"
++/*0x0386*/	BYTE $0
++#line 368 "file2.s"
++/*0x0387*/	BYTE $0
++#line 368 "file2.s"
++/*0x0388*/	BYTE $0
++#line 775 "file2.s"
++/*0x0389*/	BYTE $0
++#line 10 "file8.s"
++/*0x038a*/	BYTE $0
++#line 10 "file8.s"
++/*0x038b*/	BYTE $0
++#line 422 "file8.s"
++/*0x038c*/	MOVL $0x1234567, AX
++#line 422 "file8.s"
++/*0x0391*/	BYTE $0
++#line 613 "file8.s"
++/*0x0392*/	BYTE $0
++#line 613 "file8.s"
++/*0x0393*/	BYTE $0
++#line 613 "file8.s"
++/*0x0394*/	BYTE $0
++#line 697 "file8.s"
++/*0x0395*/	MOVQ $0x123456789, AX
++#line 697 "file8.s"
++/*0x039f*/	MOVQ $0x123456789, AX
++#line 697 "file8.s"
++/*0x03a9*/	BYTE $0
++#line 697 "file8.s"
++/*0x03aa*/	BYTE $0
++#line 697 "file8.s"
++/*0x03ab*/	BYTE $0
++	POPQ AX
++	POPQ AX
++	POPQ AX
++	RET
++
++GLOBL funcdata2(SB), $16
++
++TEXT start(SB),7,$0
++	CALL func0(SB)
++	CALL func1(SB)
++	CALL func2(SB)
++	MOVQ $runtime·pclntab(SB), AX
++
++	RET
+diff --git a/src/cmd/newlink/util.go b/src/cmd/newlink/util.go
+new file mode 100644
+index 0000000..b8a6b2c
+--- /dev/null
++++ b/src/cmd/newlink/util.go
+@@ -0,0 +1,11 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++package main
++
++// round returns size rounded up to the next multiple of align;
++// align must be a power of two.
++func round(size, align Addr) Addr {
++	return (size + align - 1) &^ (align - 1)
++}
+diff --git a/src/cmd/newlink/write.go b/src/cmd/newlink/write.go
+new file mode 100644
+index 0000000..7e11b2f
+--- /dev/null
++++ b/src/cmd/newlink/write.go
+@@ -0,0 +1,14 @@
++// Copyright 2014 The Go Authors.  All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// Writing of executable and (for hostlink mode) object files.
++
++package main
++
++import "io"
++
++func (p *Prog) write(w io.Writer) {
++	p.Entry = p.Syms[p.startSym].Addr
++	p.formatter.write(w, p)
++}
+diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
+index 8ceaba0..cd55e16 100644
+--- a/src/cmd/objdump/objdump_test.go
++++ b/src/cmd/objdump/objdump_test.go
+@@ -107,6 +107,8 @@ func TestDisasm(t *testing.T) {
+ 		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
+ 	case "mips64", "mips64le":
+ 		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
++	case "s390x":
++		t.Skipf("skipping on %s", runtime.GOARCH)
+ 	}
+ 	testDisasm(t)
+ }
+@@ -123,6 +125,8 @@ func TestDisasmExtld(t *testing.T) {
+ 		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
+ 	case "mips64", "mips64le":
+ 		t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH)
++	case "s390x":
++		t.Skipf("skipping on %s", runtime.GOARCH)
+ 	}
+ 	// TODO(jsing): Reenable once openbsd/arm has external linking support.
+ 	if runtime.GOOS == "openbsd" && runtime.GOARCH == "arm" {
+diff --git a/src/cmd/vet/asmdecl.go b/src/cmd/vet/asmdecl.go
+index e4a9871..025d3e0 100644
+--- a/src/cmd/vet/asmdecl.go
++++ b/src/cmd/vet/asmdecl.go
+@@ -65,6 +65,7 @@ var (
+ 	asmArchAmd64p32 = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
+ 	asmArchPpc64    = asmArch{"ppc64", 8, 8, 8, true, "R1", true}
+ 	asmArchPpc64LE  = asmArch{"ppc64le", 8, 8, 8, false, "R1", true}
++	asmArchS390x    = asmArch{"s390x", 8, 8, 8, true, "R15", true}
+ 
+ 	arches = []*asmArch{
+ 		&asmArch386,
+@@ -74,6 +75,7 @@ var (
+ 		&asmArchAmd64p32,
+ 		&asmArchPpc64,
+ 		&asmArchPpc64LE,
++		&asmArchS390x,
+ 	}
+ )
+ 
+diff --git a/src/crypto/aes/asm_s390x.s b/src/crypto/aes/asm_s390x.s
+new file mode 100644
+index 0000000..c9cf166
+--- /dev/null
++++ b/src/crypto/aes/asm_s390x.s
+@@ -0,0 +1,97 @@
++// Copyright 2016 The Go Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++#include "textflag.h"
++
++// func hasAsm() bool
++// returns whether the AES-128, AES-192 and AES-256
++// cipher message functions are supported.
++TEXT ·hasAsm(SB),NOSPLIT,$16-1
++	XOR    R0, R0 // set function code to 0 (query)
++	LA     8(R15), R1
++	WORD   $0xB92E0024 // KM-Query
++
++	// check if bits 18-20 are set
++	MOVD   8(R15), R2
++	SRD    $40, R2
++	AND    $0x38, R2  // mask bits 18-20 (00111000)
 +	CMPBNE R2, $0x38, notfound
 +	MOVBZ  $1, R1
 +	MOVB   R1, ret+0(FP)
@@ -21684,6 +32404,147 @@ index 6620aef..1fcc8a8 100644
  		(t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
  		return
  	}
+diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
+index 353d91f..a605628 100644
+--- a/src/encoding/csv/writer.go
++++ b/src/encoding/csv/writer.go
+@@ -130,7 +130,7 @@ func (w *Writer) fieldNeedsQuotes(field string) bool {
+ 	if field == "" {
+ 		return false
+ 	}
+-	if field == `\.` || strings.IndexRune(field, w.Comma) >= 0 || strings.IndexAny(field, "\"\r\n") >= 0 {
++	if field == `\.` || strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
+ 		return true
+ 	}
+ 
+diff --git a/src/encoding/gob/codec_test.go b/src/encoding/gob/codec_test.go
+index 8efcdc7..b772171 100644
+--- a/src/encoding/gob/codec_test.go
++++ b/src/encoding/gob/codec_test.go
+@@ -970,7 +970,7 @@ func TestBadRecursiveType(t *testing.T) {
+ 	err := NewEncoder(b).Encode(&rec)
+ 	if err == nil {
+ 		t.Error("expected error; got none")
+-	} else if strings.Index(err.Error(), "recursive") < 0 {
++	} else if !strings.Contains(err.Error(), "recursive") {
+ 		t.Error("expected recursive type error; got", err)
+ 	}
+ 	// Can't test decode easily because we can't encode one, so we can't pass one to a Decoder.
+diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go
+index 570d796..811dd2b 100644
+--- a/src/encoding/gob/encoder_test.go
++++ b/src/encoding/gob/encoder_test.go
+@@ -280,7 +280,7 @@ func TestValueError(t *testing.T) {
+ 	}
+ 	t4p := &Type4{3}
+ 	var t4 Type4 // note: not a pointer.
+-	if err := encAndDec(t4p, t4); err == nil || strings.Index(err.Error(), "pointer") < 0 {
++	if err := encAndDec(t4p, t4); err == nil || !strings.Contains(err.Error(), "pointer") {
+ 		t.Error("expected error about pointer; got", err)
+ 	}
+ }
+@@ -388,7 +388,7 @@ func TestSingletons(t *testing.T) {
+ 			t.Errorf("expected error decoding %v: %s", test.in, test.err)
+ 			continue
+ 		case err != nil && test.err != "":
+-			if strings.Index(err.Error(), test.err) < 0 {
++			if !strings.Contains(err.Error(), test.err) {
+ 				t.Errorf("wrong error decoding %v: wanted %s, got %v", test.in, test.err, err)
+ 			}
+ 			continue
+@@ -414,7 +414,7 @@ func TestStructNonStruct(t *testing.T) {
+ 	var ns NonStruct
+ 	if err := encAndDec(s, &ns); err == nil {
+ 		t.Error("should get error for struct/non-struct")
+-	} else if strings.Index(err.Error(), "type") < 0 {
++	} else if !strings.Contains(err.Error(), "type") {
+ 		t.Error("for struct/non-struct expected type error; got", err)
+ 	}
+ 	// Now try the other way
+@@ -424,7 +424,7 @@ func TestStructNonStruct(t *testing.T) {
+ 	}
+ 	if err := encAndDec(ns, &s); err == nil {
+ 		t.Error("should get error for non-struct/struct")
+-	} else if strings.Index(err.Error(), "type") < 0 {
++	} else if !strings.Contains(err.Error(), "type") {
+ 		t.Error("for non-struct/struct expected type error; got", err)
+ 	}
+ }
+diff --git a/src/encoding/gob/gobencdec_test.go b/src/encoding/gob/gobencdec_test.go
+index eb76b48..d674f0c 100644
+--- a/src/encoding/gob/gobencdec_test.go
++++ b/src/encoding/gob/gobencdec_test.go
+@@ -548,7 +548,7 @@ func TestGobEncoderFieldTypeError(t *testing.T) {
+ 	if err == nil {
+ 		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
+ 	}
+-	if strings.Index(err.Error(), "type") < 0 {
++	if !strings.Contains(err.Error(), "type") {
+ 		t.Fatal("expected type error; got", err)
+ 	}
+ 	// Non-encoder to GobDecoder: error
+@@ -562,7 +562,7 @@ func TestGobEncoderFieldTypeError(t *testing.T) {
+ 	if err == nil {
+ 		t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
+ 	}
+-	if strings.Index(err.Error(), "type") < 0 {
++	if !strings.Contains(err.Error(), "type") {
+ 		t.Fatal("expected type error; got", err)
+ 	}
+ }
+diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
+index 8ebd693..9fcd5d7 100644
+--- a/src/encoding/xml/marshal.go
++++ b/src/encoding/xml/marshal.go
+@@ -850,7 +850,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
+ 			switch k {
+ 			case reflect.String:
+ 				s := vf.String()
+-				dashDash = strings.Index(s, "--") >= 0
++				dashDash = strings.Contains(s, "--")
+ 				dashLast = s[len(s)-1] == '-'
+ 				if !dashDash {
+ 					p.WriteString(s)
+diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
+index 7ac74dc..ce6f086 100644
+--- a/src/fmt/scan_test.go
++++ b/src/fmt/scan_test.go
+@@ -519,7 +519,7 @@ func testScanfMulti(name string, t *testing.T) {
+ 		if err != nil {
+ 			if test.err == "" {
+ 				t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
+-			} else if strings.Index(err.Error(), test.err) < 0 {
++			} else if !strings.Contains(err.Error(), test.err) {
+ 				t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
+ 			}
+ 			continue
+@@ -613,7 +613,7 @@ func TestScanNotPointer(t *testing.T) {
+ 	_, err := Fscan(r, a)
+ 	if err == nil {
+ 		t.Error("expected error scanning non-pointer")
+-	} else if strings.Index(err.Error(), "pointer") < 0 {
++	} else if !strings.Contains(err.Error(), "pointer") {
+ 		t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
+ 	}
+ }
+@@ -623,7 +623,7 @@ func TestScanlnNoNewline(t *testing.T) {
+ 	_, err := Sscanln("1 x\n", &a)
+ 	if err == nil {
+ 		t.Error("expected error scanning string missing newline")
+-	} else if strings.Index(err.Error(), "newline") < 0 {
++	} else if !strings.Contains(err.Error(), "newline") {
+ 		t.Errorf("expected newline error scanning string missing newline, got: %s", err)
+ 	}
+ }
+@@ -634,7 +634,7 @@ func TestScanlnWithMiddleNewline(t *testing.T) {
+ 	_, err := Fscanln(r, &a, &b)
+ 	if err == nil {
+ 		t.Error("expected error scanning string with extra newline")
+-	} else if strings.Index(err.Error(), "newline") < 0 {
++	} else if !strings.Contains(err.Error(), "newline") {
+ 		t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
+ 	}
+ }
 diff --git a/src/go/build/build.go b/src/go/build/build.go
 index c1b70bc..4cfc4be 100644
 --- a/src/go/build/build.go
@@ -21696,6 +32557,62 @@ index c1b70bc..4cfc4be 100644
  }
  
  func defaultContext() Context {
+diff --git a/src/go/constant/value.go b/src/go/constant/value.go
+index 310814d..1b0938d 100644
+--- a/src/go/constant/value.go
++++ b/src/go/constant/value.go
+@@ -276,10 +276,10 @@ func smallRat(x *big.Float) bool {
+ // MakeUnknown returns the Unknown value.
+ func MakeUnknown() Value { return unknownVal{} }
+ 
+-// MakeBool returns the Bool value for x.
++// MakeBool returns the Bool value for b.
+ func MakeBool(b bool) Value { return boolVal(b) }
+ 
+-// MakeString returns the String value for x.
++// MakeString returns the String value for s.
+ func MakeString(s string) Value { return stringVal(s) }
+ 
+ // MakeInt64 returns the Int value for x.
+diff --git a/src/go/doc/comment.go b/src/go/doc/comment.go
+index f414ca4..5631539 100644
+--- a/src/go/doc/comment.go
++++ b/src/go/doc/comment.go
+@@ -225,7 +225,7 @@ func heading(line string) string {
+ 	}
+ 
+ 	// exclude lines with illegal characters
+-	if strings.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 {
++	if strings.ContainsAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") {
+ 		return ""
+ 	}
+ 
+diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
+index d70ec08..052277f 100644
+--- a/src/go/internal/gcimporter/gcimporter.go
++++ b/src/go/internal/gcimporter/gcimporter.go
+@@ -385,7 +385,7 @@ func (p *parser) getPkg(id, name string) *types.Package {
+ 		if pname := pkg.Name(); pname == "" {
+ 			pkg.SetName(name)
+ 		} else if pname != name {
+-			p.errorf("%s package name mismatch: %s (given) vs %s (expected)", pname, name)
++			p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
+ 		}
+ 	}
+ 	return pkg
+diff --git a/src/go/types/universe.go b/src/go/types/universe.go
+index 40185c1..cc3bd5a 100644
+--- a/src/go/types/universe.go
++++ b/src/go/types/universe.go
+@@ -196,7 +196,7 @@ func init() {
+ //
+ func def(obj Object) {
+ 	name := obj.Name()
+-	if strings.Index(name, " ") >= 0 {
++	if strings.Contains(name, " ") {
+ 		return // nothing to do
+ 	}
+ 	// fix Obj link for named types
 diff --git a/src/hash/crc32/crc32_generic.go b/src/hash/crc32/crc32_generic.go
 index 8fc11a7..25f2d55 100644
 --- a/src/hash/crc32/crc32_generic.go
@@ -21724,7 +32641,7 @@ index 0000000..d435f71
 +const randomTrap uintptr = 349
 diff --git a/src/math/big/arith_s390x.s b/src/math/big/arith_s390x.s
 new file mode 100644
-index 0000000..d296d64
+index 0000000..35ed863
 --- /dev/null
 +++ b/src/math/big/arith_s390x.s
 @@ -0,0 +1,574 @@
@@ -21771,7 +32688,7 @@ index 0000000..d296d64
 +
 +	// s/JL/JMP/ below to disable the unrolled loop
 +	SUB  $4, R3		// n -= 4
-+	BLT V1			// if n < 0 goto V1
++	BLT v1			// if n < 0 goto v1
 +
 +U1:	// n >= 0
 +	// regular loop body unrolled 4x
@@ -21801,7 +32718,7 @@ index 0000000..d296d64
 +	SUB  $4,  R3		// n -= 4
 +	BGE  U1			// if n >= 0 goto U1
 +
-+V1:	ADD  $4, R3		// n += 4
++v1:	ADD  $4, R3		// n += 4
 +	BLE E1			// if n <= 0 goto E1
 +
 +L1:	// n > 0
@@ -21837,7 +32754,7 @@ index 0000000..d296d64
 +
 +	// s/JL/JMP/ below to disable the unrolled loop
 +	SUB  $4, R3		// n -= 4
-+	BLT V1			// if n < 0 goto V1
++	BLT v1			// if n < 0 goto v1
 +
 +U1:	// n >= 0
 +	// regular loop body unrolled 4x
@@ -21867,7 +32784,7 @@ index 0000000..d296d64
 +	SUB  $4,  R3		// n -= 4
 +	BGE  U1			// if n >= 0 goto U1
 +
-+V1:	ADD  $4, R3		// n += 4
++v1:	ADD  $4, R3		// n += 4
 +	BLE E1			// if n <= 0 goto E1
 +
 +L1:	// n > 0
@@ -21901,7 +32818,7 @@ index 0000000..d296d64
 +
 +	// s/JL/JMP/ below to disable the unrolled loop
 +	SUB $4, R3		// n -= 4
-+	BLT V4			// if n < 4 goto V4
++	BLT v4			// if n < 4 goto v4
 +
 +U4:	// n >= 0
 +	// regular loop body unrolled 4x
@@ -21925,7 +32842,7 @@ index 0000000..d296d64
 +	SUB $4, R3		// n -= 4
 +	BGE U4			// if n >= 0 goto U4
 +
-+V4:	ADD $4, R3		// n += 4
++v4:	ADD $4, R3		// n += 4
 +	BLE E4			// if n <= 0 goto E4
 +
 +L4:	// n > 0
@@ -21957,7 +32874,7 @@ index 0000000..d296d64
 +
 +	// s/JL/JMP/ below to disable the unrolled loop
 +	SUB $4, R3		// n -= 4
-+	BLT V4			// if n < 4 goto V4
++	BLT v4			// if n < 4 goto v4
 +
 +U4:	// n >= 0
 +	// regular loop body unrolled 4x
@@ -21980,7 +32897,7 @@ index 0000000..d296d64
 +	SUB $4, R3		// n -= 4
 +	BGE U4			// if n >= 0 goto U4
 +
-+V4:	ADD $4, R3		// n += 4
++v4:	ADD $4, R3		// n += 4
 +	BLE E4			// if n <= 0 goto E4
 +
 +L4:	// n > 0
@@ -22302,6 +33219,28 @@ index 0000000..d296d64
 +	SUB  R2, R3
 +	MOVD R3, n+8(FP)
 +	RET
+diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
+index 4566ff4..57df124 100644
+--- a/src/math/big/ratconv.go
++++ b/src/math/big/ratconv.go
+@@ -15,7 +15,7 @@ import (
+ )
+ 
+ func ratTok(ch rune) bool {
+-	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
++	return strings.ContainsRune("+-/0123456789.eE", ch)
+ }
+ 
+ // Scan is a support routine for fmt.Scanner. It accepts the formats
+@@ -25,7 +25,7 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
+ 	if err != nil {
+ 		return err
+ 	}
+-	if strings.IndexRune("efgEFGv", ch) < 0 {
++	if !strings.ContainsRune("efgEFGv", ch) {
+ 		return errors.New("Rat.Scan: invalid verb")
+ 	}
+ 	if _, ok := z.SetString(string(tok)); !ok {
 diff --git a/src/math/dim_s390x.s b/src/math/dim_s390x.s
 new file mode 100644
 index 0000000..55c8ac1
@@ -22541,6 +33480,228 @@ index 0000000..305480e
 +
 +TEXT ·Tan(SB),NOSPLIT,$0
 +	BR ·tan(SB)
+diff --git a/src/mime/grammar.go b/src/mime/grammar.go
+index 31b66e8..6a6f71d 100644
+--- a/src/mime/grammar.go
++++ b/src/mime/grammar.go
+@@ -11,7 +11,7 @@ import (
+ // isTSpecial reports whether rune is in 'tspecials' as defined by RFC
+ // 1521 and RFC 2045.
+ func isTSpecial(r rune) bool {
+-	return strings.IndexRune(`()<>@,;:\"/[]?=`, r) != -1
++	return strings.ContainsRune(`()<>@,;:\"/[]?=`, r)
+ }
+ 
+ // isTokenChar reports whether rune is in 'token' as defined by RFC
+diff --git a/src/net/dnsmsg.go b/src/net/dnsmsg.go
+index 93078fe..2ec4c8c 100644
+--- a/src/net/dnsmsg.go
++++ b/src/net/dnsmsg.go
+@@ -406,6 +406,13 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
+ 		s += "."
+ 	}
+ 
++	// Allow root domain.
++	if s == "." {
++		msg[off] = 0
++		off++
++		return off, true
++	}
++
+ 	// Each dot ends a segment of the name.
+ 	// We trade each dot byte for a length byte.
+ 	// There is also a trailing zero.
+@@ -422,8 +429,13 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
+ 			if i-begin >= 1<<6 { // top two bits of length must be clear
+ 				return len(msg), false
+ 			}
++			if i-begin == 0 {
++				return len(msg), false
++			}
++
+ 			msg[off] = byte(i - begin)
+ 			off++
++
+ 			for j := begin; j < i; j++ {
+ 				msg[off] = s[j]
+ 				off++
+@@ -494,6 +506,9 @@ Loop:
+ 			return "", len(msg), false
+ 		}
+ 	}
++	if len(s) == 0 {
++		s = "."
++	}
+ 	if ptr == 0 {
+ 		off1 = off
+ 	}
+@@ -803,20 +818,32 @@ func (dns *dnsMsg) Pack() (msg []byte, ok bool) {
+ 	// Pack it in: header and then the pieces.
+ 	off := 0
+ 	off, ok = packStruct(&dh, msg, off)
++	if !ok {
++		return nil, false
++	}
+ 	for i := 0; i < len(question); i++ {
+ 		off, ok = packStruct(&question[i], msg, off)
++		if !ok {
++			return nil, false
++		}
+ 	}
+ 	for i := 0; i < len(answer); i++ {
+ 		off, ok = packRR(answer[i], msg, off)
++		if !ok {
++			return nil, false
++		}
+ 	}
+ 	for i := 0; i < len(ns); i++ {
+ 		off, ok = packRR(ns[i], msg, off)
++		if !ok {
++			return nil, false
++		}
+ 	}
+ 	for i := 0; i < len(extra); i++ {
+ 		off, ok = packRR(extra[i], msg, off)
+-	}
+-	if !ok {
+-		return nil, false
++		if !ok {
++			return nil, false
++		}
+ 	}
+ 	return msg[0:off], true
+ }
+@@ -848,6 +875,9 @@ func (dns *dnsMsg) Unpack(msg []byte) bool {
+ 
+ 	for i := 0; i < len(dns.question); i++ {
+ 		off, ok = unpackStruct(&dns.question[i], msg, off)
++		if !ok {
++			return false
++		}
+ 	}
+ 	for i := 0; i < int(dh.Ancount); i++ {
+ 		rec, off, ok = unpackRR(msg, off)
+diff --git a/src/net/dnsmsg_test.go b/src/net/dnsmsg_test.go
+index 1078d77..339fb83 100644
+--- a/src/net/dnsmsg_test.go
++++ b/src/net/dnsmsg_test.go
+@@ -10,6 +10,103 @@ import (
+ 	"testing"
+ )
+ 
++func TestStructPackUnpack(t *testing.T) {
++	want := dnsQuestion{
++		Name:   ".",
++		Qtype:  dnsTypeA,
++		Qclass: dnsClassINET,
++	}
++	buf := make([]byte, 50)
++	n, ok := packStruct(&want, buf, 0)
++	if !ok {
++		t.Fatal("packing failed")
++	}
++	buf = buf[:n]
++	got := dnsQuestion{}
++	n, ok = unpackStruct(&got, buf, 0)
++	if !ok {
++		t.Fatal("unpacking failed")
++	}
++	if n != len(buf) {
++		t.Error("unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
++	}
++	if !reflect.DeepEqual(got, want) {
++		t.Errorf("got = %+v, want = %+v", got, want)
++	}
++}
++
++func TestDomainNamePackUnpack(t *testing.T) {
++	tests := []struct {
++		in   string
++		want string
++		ok   bool
++	}{
++		{"", ".", true},
++		{".", ".", true},
++		{"google..com", "", false},
++		{"google.com", "google.com.", true},
++		{"google..com.", "", false},
++		{"google.com.", "google.com.", true},
++		{".google.com.", "", false},
++		{"www..google.com.", "", false},
++		{"www.google.com.", "www.google.com.", true},
++	}
++
++	for _, test := range tests {
++		buf := make([]byte, 30)
++		n, ok := packDomainName(test.in, buf, 0)
++		if ok != test.ok {
++			t.Errorf("packing of %s: got ok = %t, want = %t", test.in, ok, test.ok)
++			continue
++		}
++		if !test.ok {
++			continue
++		}
++		buf = buf[:n]
++		got, n, ok := unpackDomainName(buf, 0)
++		if !ok {
++			t.Errorf("unpacking for %s failed", test.in)
++			continue
++		}
++		if n != len(buf) {
++			t.Error(
++				"unpacked different amount than packed for %s: got n = %d, want = %d",
++				test.in,
++				n,
++				len(buf),
++			)
++		}
++		if got != test.want {
++			t.Errorf("unpacking packing of %s: got = %s, want = %s", test.in, got, test.want)
++		}
++	}
++}
++
++func TestDNSPackUnpack(t *testing.T) {
++	want := dnsMsg{
++		question: []dnsQuestion{{
++			Name:   ".",
++			Qtype:  dnsTypeAAAA,
++			Qclass: dnsClassINET,
++		}},
++		answer: []dnsRR{},
++		ns:     []dnsRR{},
++		extra:  []dnsRR{},
++	}
++	b, ok := want.Pack()
++	if !ok {
++		t.Fatal("packing failed")
++	}
++	var got dnsMsg
++	ok = got.Unpack(b)
++	if !ok {
++		t.Fatal("unpacking failed")
++	}
++	if !reflect.DeepEqual(got, want) {
++		t.Errorf("got = %+v, want = %+v", got, want)
++	}
++}
++
+ func TestDNSParseSRVReply(t *testing.T) {
+ 	data, err := hex.DecodeString(dnsSRVReply)
+ 	if err != nil {
+diff --git a/src/net/http/fs.go b/src/net/http/fs.go
+index f61c138..8a5b8bb 100644
+--- a/src/net/http/fs.go
++++ b/src/net/http/fs.go
+@@ -34,7 +34,7 @@ import (
+ type Dir string
+ 
+ func (d Dir) Open(name string) (File, error) {
+-	if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
++	if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) ||
+ 		strings.Contains(name, "\x00") {
+ 		return nil, errors.New("http: invalid character in file path")
+ 	}
 diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
 index 69d7806..9799ec7 100644
 --- a/src/net/http/fs_test.go
@@ -22558,6 +33719,43 @@ index 69d7806..9799ec7 100644
  		syscalls = "sendfile"
  	}
  
+diff --git a/src/net/http/transport.go b/src/net/http/transport.go
+index baf71d5..1e3ea11 100644
+--- a/src/net/http/transport.go
++++ b/src/net/http/transport.go
+@@ -176,9 +176,13 @@ func (t *Transport) onceSetNextProtoDefaults() {
+ 		// Issue 14275.
+ 		return
+ 	}
+-	if t.ExpectContinueTimeout != 0 {
+-		// Unsupported in http2, so disable http2 for now.
+-		// Issue 13851.
++	if t.ExpectContinueTimeout != 0 && t != DefaultTransport {
++		// ExpectContinueTimeout is unsupported in http2, so
++		// if they explicitly asked for it (as opposed to just
++		// using the DefaultTransport, which sets it), then
++		// disable http2 for now.
++		//
++		// Issue 13851. (and changed in Issue 14391)
+ 		return
+ 	}
+ 	t2, err := http2configureTransport(t)
+diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
+index 0c901b3..d9da078 100644
+--- a/src/net/http/transport_test.go
++++ b/src/net/http/transport_test.go
+@@ -2888,6 +2888,11 @@ func TestTransportAutomaticHTTP2(t *testing.T) {
+ 	testTransportAutoHTTP(t, &Transport{}, true)
+ }
+ 
++// golang.org/issue/14391: also check DefaultTransport
++func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
++	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
++}
++
+ func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
+ 	testTransportAutoHTTP(t, &Transport{
+ 		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
 diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
 index 439496a..f8f69c7 100644
 --- a/src/net/lookup_test.go
@@ -22574,6 +33772,100 @@ index 439496a..f8f69c7 100644
  	for _, tt := range lookupPortTests {
  		if port, err := LookupPort(tt.network, tt.name); port != tt.port || (err == nil) != tt.ok {
  			t.Errorf("LookupPort(%q, %q) = %d, %v; want %d", tt.network, tt.name, port, err, tt.port)
+diff --git a/src/net/rpc/server_test.go b/src/net/rpc/server_test.go
+index 8871c88..cf171ac 100644
+--- a/src/net/rpc/server_test.go
++++ b/src/net/rpc/server_test.go
+@@ -183,7 +183,7 @@ func testRPC(t *testing.T, addr string) {
+ 	err = client.Call("Arith.Unknown", args, reply)
+ 	if err == nil {
+ 		t.Error("expected error calling unknown service")
+-	} else if strings.Index(err.Error(), "method") < 0 {
++	} else if !strings.Contains(err.Error(), "method") {
+ 		t.Error("expected error about method; got", err)
+ 	}
+ 
+@@ -226,7 +226,7 @@ func testRPC(t *testing.T, addr string) {
+ 	err = client.Call("Arith.Add", reply, reply) // args, reply would be the correct thing to use
+ 	if err == nil {
+ 		t.Error("expected error calling Arith.Add with wrong arg type")
+-	} else if strings.Index(err.Error(), "type") < 0 {
++	} else if !strings.Contains(err.Error(), "type") {
+ 		t.Error("expected error about type; got", err)
+ 	}
+ 
+diff --git a/src/net/url/url.go b/src/net/url/url.go
+index 1a93e34..b7e25ec 100644
+--- a/src/net/url/url.go
++++ b/src/net/url/url.go
+@@ -511,7 +511,7 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) {
+ 		return nil, host, nil
+ 	}
+ 	userinfo := authority[:i]
+-	if strings.Index(userinfo, ":") < 0 {
++	if !strings.Contains(userinfo, ":") {
+ 		if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
+ 			return nil, "", err
+ 		}
+diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
+index c3efd67..0b0712d 100644
+--- a/src/os/exec/lp_windows.go
++++ b/src/os/exec/lp_windows.go
+@@ -70,7 +70,7 @@ func LookPath(file string) (f string, err error) {
+ 		}
+ 		exts = append(exts, e)
+ 	}
+-	if strings.IndexAny(file, `:\/`) != -1 {
++	if strings.ContainsAny(file, `:\/`) {
+ 		if f, err = findExecutable(file, exts); err == nil {
+ 			return
+ 		}
+diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go
+index 89f16de..d64bf84 100644
+--- a/src/path/filepath/match.go
++++ b/src/path/filepath/match.go
+@@ -49,7 +49,7 @@ Pattern:
+ 		star, chunk, pattern = scanChunk(pattern)
+ 		if star && chunk == "" {
+ 			// Trailing * matches rest of string unless it has a /.
+-			return strings.Index(name, string(Separator)) < 0, nil
++			return !strings.Contains(name, string(Separator)), nil
+ 		}
+ 		// Look for match at current position.
+ 		t, ok, err := matchChunk(chunk, name)
+@@ -305,5 +305,5 @@ func glob(dir, pattern string, matches []string) (m []string, e error) {
+ // recognized by Match.
+ func hasMeta(path string) bool {
+ 	// TODO(niemeyer): Should other magic characters be added here?
+-	return strings.IndexAny(path, "*?[") >= 0
++	return strings.ContainsAny(path, "*?[")
+ }
+diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go
+index 0edbfc7..d8bab7f 100644
+--- a/src/path/filepath/match_test.go
++++ b/src/path/filepath/match_test.go
+@@ -88,7 +88,7 @@ func TestMatch(t *testing.T) {
+ 		pattern := tt.pattern
+ 		s := tt.s
+ 		if runtime.GOOS == "windows" {
+-			if strings.Index(pattern, "\\") >= 0 {
++			if strings.Contains(pattern, "\\") {
+ 				// no escape allowed on windows.
+ 				continue
+ 			}
+diff --git a/src/path/match.go b/src/path/match.go
+index 75dd3b3..8d9aa51 100644
+--- a/src/path/match.go
++++ b/src/path/match.go
+@@ -43,7 +43,7 @@ Pattern:
+ 		star, chunk, pattern = scanChunk(pattern)
+ 		if star && chunk == "" {
+ 			// Trailing * matches rest of string unless it has a /.
+-			return strings.Index(name, "/") < 0, nil
++			return !strings.Contains(name, "/"), nil
+ 		}
+ 		// Look for match at current position.
+ 		t, ok, err := matchChunk(chunk, name)
 diff --git a/src/reflect/asm_s390x.s b/src/reflect/asm_s390x.s
 new file mode 100644
 index 0000000..4810d46
@@ -22610,12 +33902,38 @@ index 0000000..4810d46
 +	MOVD	R3, 16(R15)
 +	BL	·callMethod(SB)
 +	RET
+diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go
+index d7d0edb..42ae6e1 100644
+--- a/src/regexp/regexp.go
++++ b/src/regexp/regexp.go
+@@ -454,7 +454,7 @@ func Match(pattern string, b []byte) (matched bool, err error) {
+ // in Expand, so for instance $1 represents the text of the first submatch.
+ func (re *Regexp) ReplaceAllString(src, repl string) string {
+ 	n := 2
+-	if strings.Index(repl, "$") >= 0 {
++	if strings.Contains(repl, "$") {
+ 		n = 2 * (re.numSubexp + 1)
+ 	}
+ 	b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
+diff --git a/src/regexp/syntax/regexp.go b/src/regexp/syntax/regexp.go
+index 75822cf..ca57240 100644
+--- a/src/regexp/syntax/regexp.go
++++ b/src/regexp/syntax/regexp.go
+@@ -252,7 +252,7 @@ const meta = `\.+*?()|[]{}^$`
+ 
+ func escape(b *bytes.Buffer, r rune, force bool) {
+ 	if unicode.IsPrint(r) {
+-		if strings.IndexRune(meta, r) >= 0 || force {
++		if strings.ContainsRune(meta, r) || force {
+ 			b.WriteRune('\\')
+ 		}
+ 		b.WriteRune(r)
 diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
 new file mode 100644
-index 0000000..861747e
+index 0000000..3390dc8
 --- /dev/null
 +++ b/src/runtime/asm_s390x.s
-@@ -0,0 +1,1182 @@
+@@ -0,0 +1,1122 @@
 +// Copyright 2016 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -22625,6 +33943,25 @@ index 0000000..861747e
 +#include "funcdata.h"
 +#include "textflag.h"
 +
++DATA runtime·vectorfacility+0x00(SB)/4, $0
++GLOBL runtime·vectorfacility(SB), NOPTR, $4
++
++TEXT runtime·checkvectorfacility(SB),NOSPLIT,$24-0
++	MOVD	$2, R0
++	MOVD	$x-24(SP), R1
++	// STFLE 0(R1)
++	WORD	$0xB2B01000
++	MOVBZ	z-8(SP), R1
++	AND	$0x40, R1
++	BNE	setvector
++	MOVD	$0, R0
++	RET
++setvector:
++	MOVD	$1, R1
++	MOVBZ	R1, runtime·vectorfacility(SB)
++	MOVD	$0, R0
++	RET
++
 +TEXT runtime·rt0_go(SB),NOSPLIT,$0
 +	// R2 = argc; R3 = argv; R11 = temp; R13 = g; R15 = stack pointer
 +	// C TLS base pointer in AR0:AR1
@@ -22686,6 +34023,9 @@ index 0000000..861747e
 +	BL	runtime·osinit(SB)
 +	BL	runtime·schedinit(SB)
 +
++	// check and set the vectorfacility
++	BL	runtime·checkvectorfacility(SB)
++
 +	// create a new goroutine to start program
 +	MOVD	$runtime·mainPC(SB), R2		// entry
 +	SUB     $24, R15
@@ -23314,9 +34654,6 @@ index 0000000..861747e
 +	MOVW	(R0), R0
 +	UNDEF
 +
-+#define	TBRL	268
-+#define	TBRU	269		/* Time base Upper/Lower */
-+
 +// int64 runtime·cputicks(void)
 +TEXT runtime·cputicks(SB),NOSPLIT,$0-8
 +	// The TOD clock on s390 counts from the year 1900 in ~250ps intervals.
@@ -23357,215 +34694,113 @@ index 0000000..861747e
 +TEXT runtime·aeshashstr(SB),NOSPLIT|NOFRAME,$0-0
 +	MOVW	(R0), R15
 +
-+TEXT runtime·clc(SB),NOSPLIT,$0-0
-+	CLC	$1, 0(R3), 0(R4)
-+	RET
-+
 +TEXT runtime·memeq(SB),NOSPLIT|NOFRAME,$0-25
 +	MOVD	a+0(FP), R3
-+	MOVD	b+8(FP), R4
-+	CMPBNE	R3, R4, 4(PC)
-+	MOVD	$1, R5
-+	MOVB	R5, ret+24(FP)
-+	RET
-+	MOVD	size+16(FP), R5
-+loop:
-+	CMPBEQ	R5, $0, equal
-+	CMP	R5, $256
-+	BLT	tail
-+	CLC	$256, 0(R3), 0(R4)
-+	BNE	notequal
-+	SUB	$256, R5
-+	ADD	$256, R3
-+	ADD	$256, R4
-+	BR	loop
-+tail:
-+	SUB	$1, R5
-+	EXRL	$runtime·clc(SB), R5
-+	BEQ	equal
-+	MOVB	R0, ret+24(FP)
-+	RET
-+equal:
-+	MOVD	$1, R5
-+	MOVB	R5, ret+24(FP)
-+	RET
-+notequal:
-+	MOVB	R0, ret+24(FP)
-+	RET
++	MOVD	b+8(FP), R5
++	MOVD	size+16(FP), R6
++	LA	ret+24(FP), R7
++	BR	runtime·memeqbody(SB)
 +
 +// memequal_varlen(a, b unsafe.Pointer) bool
-+TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17
++TEXT runtime·memequal_varlen(SB),NOSPLIT|NOFRAME,$0-17
 +	MOVD	a+0(FP), R3
-+	MOVD	b+8(FP), R4
-+	CMPBEQ	R3, R4, eq
-+	MOVD	8(R12), R5    // compiler stores size at offset 8 in the closure
-+	MOVD	R3, 8(R15)
-+	MOVD	R4, 16(R15)
-+	MOVD	R5, 24(R15)
-+	BL	runtime·memeq(SB)
-+	MOVBZ	32(R15), R3
-+	MOVB	R3, ret+16(FP)
-+	RET
-+eq:
-+	MOVD	$1, R3
-+	MOVB	R3, ret+16(FP)
-+	RET
++	MOVD	b+8(FP), R5
++	MOVD	8(R12), R6    // compiler stores size at offset 8 in the closure
++	LA	ret+16(FP), R7
++	BR	runtime·memeqbody(SB)
 +
 +// eqstring tests whether two strings are equal.
 +// The compiler guarantees that strings passed
 +// to eqstring have equal length.
 +// See runtime_test.go:eqstring_generic for
 +// equivalent Go code.
-+TEXT runtime·eqstring(SB),NOSPLIT,$0-33
++TEXT runtime·eqstring(SB),NOSPLIT|NOFRAME,$0-33
 +	MOVD	s1str+0(FP), R3
-+	MOVD	s2str+16(FP), R4
-+	CMPBNE	R3, R4, 4(PC)
-+	MOVD	$1, R5
-+	MOVB	R5, ret+32(FP)
++	MOVD	s1len+8(FP), R6
++	MOVD	s2str+16(FP), R5
++	LA	ret+32(FP), R7
++	BR	runtime·memeqbody(SB)
++
++TEXT bytes·Equal(SB),NOSPLIT|NOFRAME,$0-49
++	MOVD	a_len+8(FP), R2
++	MOVD	b_len+32(FP), R6
++	MOVD	a+0(FP), R3
++	MOVD	b+24(FP), R5
++	LA	ret+48(FP), R7
++	CMPBNE	R2, R6, notequal
++	BR	runtime·memeqbody(SB)
++notequal:
++	MOVB	$0, ret+48(FP)
 +	RET
-+	MOVD	s1len+8(FP), R5
++
++// input:
++//   R3 = a
++//   R5 = b
++//   R6 = len
++//   R7 = address of output byte (stores 0 or 1 here)
++//   a and b have the same length
++TEXT runtime·memeqbody(SB),NOSPLIT|NOFRAME,$0-0
++	CMPBEQ	R3, R5, equal
 +loop:
-+	CMPBEQ	R5, $0, equal
-+	CMP	R5, $256
++	CMPBEQ	R6, $0, equal
++	CMPBLT	R6, $32, tiny
++	CMP	R6, $256
 +	BLT	tail
-+	CLC	$256, 0(R3), 0(R4)
++	CLC	$256, 0(R3), 0(R5)
 +	BNE	notequal
-+	SUB	$256, R5
-+	ADD	$256, R3
-+	ADD	$256, R4
++	SUB	$256, R6
++	LA	256(R3), R3
++	LA	256(R5), R5
 +	BR	loop
 +tail:
-+	SUB	$1, R5
-+	EXRL	$runtime·clc(SB), R5
++	SUB	$1, R6, R8
++	EXRL	$runtime·memeqbodyclc(SB), R8
 +	BEQ	equal
-+	MOVB	R0, ret+32(FP)
-+	RET
-+equal:
-+	MOVD	$1, R5
-+	MOVB	R5, ret+32(FP)
-+	RET
 +notequal:
-+	MOVB	R0, ret+32(FP)
-+	RET
-+
-+// TODO: share code with memeq?
-+TEXT bytes·Equal(SB),NOSPLIT,$0-49
-+	MOVD	a_len+8(FP), R5
-+	MOVD	b_len+32(FP), R6
-+	CMPBNE	R5, R6, notequal
-+	MOVD	a+0(FP), R3
-+	MOVD	b+24(FP), R4
-+	CMPBLE	R5, $32, tiny
-+	CMP	R5, $256
-+	BGT	loop
-+tail:
-+	SUB	$1, R5
-+	EXRL	$runtime·clc(SB), R5
-+	BEQ	equal
-+	MOVB	R0, ret+48(FP)
++	MOVB	$0, 0(R7)
 +	RET
-+loop:
-+	CLC	$256, 0(R3), 0(R4)
-+	BNE	notequal
-+	SUB	$256, R5
-+	ADD	$256, R3
-+	ADD	$256, R4
-+	CMP	R5, $256
-+	BGE	loop
-+	CMPBNE	R5, $0, tail
 +equal:
-+	MOVD	$1, R5
-+	MOVB	R5, ret+48(FP)
-+	RET
-+notequal:
-+	MOVB	R0, ret+48(FP)
++	MOVB	$1, 0(R7)
 +	RET
 +tiny:
-+	CMPBLT	R5, $16, lt16
-+	MOVD	0(R3), R6
-+	MOVD	0(R4), R7
-+	CMPBNE	R6, R7, notequal
-+	MOVD	8(R3), R6
-+	MOVD	8(R4), R7
-+	CMPBNE	R6, R7, notequal
-+	ADD 	$16, R3
-+	ADD	$16, R4
-+	SUB	$16, R5
++	MOVD	$0, R2
++	CMPBLT	R6, $16, lt16
++	MOVD	0(R3), R8
++	MOVD	0(R5), R9
++	CMPBNE	R8, R9, notequal
++	MOVD	8(R3), R8
++	MOVD	8(R5), R9
++	CMPBNE	R8, R9, notequal
++	LA	16(R2), R2
++	SUB	$16, R6
 +lt16:
-+	CMPBLT	R5, $8, lt8
-+	MOVD	0(R3), R6
-+	MOVD	0(R4), R7
-+	CMPBNE	R6, R7, notequal
-+	ADD	$8, R3
-+	ADD	$8, R4
-+	SUB	$8, R5
++	CMPBLT	R6, $8, lt8
++	MOVD	0(R3)(R2*1), R8
++	MOVD	0(R5)(R2*1), R9
++	CMPBNE	R8, R9, notequal
++	LA	8(R2), R2
++	SUB	$8, R6
 +lt8:
-+	CMPBLT	R5, $4, lt4
-+	MOVWZ	0(R3), R6
-+	MOVWZ	0(R4), R7
-+	CMPBNE	R6, R7, notequal
-+	ADD	$4, R3
-+	ADD	$4, R4
-+	SUB	$4, R5
++	CMPBLT	R6, $4, lt4
++	MOVWZ	0(R3)(R2*1), R8
++	MOVWZ	0(R5)(R2*1), R9
++	CMPBNE	R8, R9, notequal
++	LA	4(R2), R2
++	SUB	$4, R6
 +lt4:
 +#define CHECK(n) \
-+	CMPBEQ	R5, $n, equal \
-+	MOVB	n(R3), R6 \
-+	MOVB	n(R4), R7 \
-+	CMP	R6, R7 \
-+	BNE	notequal
++	CMPBEQ	R6, $n, equal \
++	MOVB	n(R3)(R2*1), R8 \
++	MOVB	n(R5)(R2*1), R9 \
++	CMPBNE	R8, R9, notequal
 +	CHECK(0)
 +	CHECK(1)
 +	CHECK(2)
 +	CHECK(3)
 +	BR	equal
 +
-+TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
-+	MOVD	s+0(FP), R3
-+	MOVD	s_len+8(FP), R4
-+	MOVBZ	c+24(FP), R5	// byte to find
-+	CMP	R4, $0
-+	BEQ	notfound
-+	MOVD	R3, R6		// store base for later
-+	ADD	R3, R4		// calculate end marker
-+	MOVBZ	R5, R0		// c needs to be in R0, leave until last minute as currently R0 is expected to be 0
-+loop:
-+	WORD	$0xB25E0043	// srst %r4, %r3 (search the range [R3, R4))
-+	BVS	loop		// interrupted - continue
-+	BGT	notfound
-+found:
-+	XOR	R0, R0		// reset R0
-+	SUB	R6, R4		// remove base
-+	MOVD	R4, ret+32(FP)
-+	RET
-+notfound:
-+	XOR	R0, R0		// reset R0
-+	MOVD	$-1, R1
-+	MOVD	R1, ret+32(FP)
-+	RET
-+
-+TEXT strings·IndexByte(SB),NOSPLIT,$0-32
-+	MOVD	p+0(FP), R3
-+	MOVD	b_len+8(FP), R4
-+	MOVBZ	c+16(FP), R5	// byte to find
-+	CMP	R4, $0
-+	BEQ	notfound
-+	MOVD	R3, R6		// store base for later
-+	ADD	R3, R4		// calculate end marker
-+	MOVBZ	R5, R0		// c needs to be in R0, leave until last minute as currently R0 is expected to be 0
-+loop:
-+	WORD	$0xB25E0043	// srst %r4, %r3 (search the range [R3, R4))
-+	BVS	loop		// interrupted - continue
-+	BGT	notfound
-+found:
-+	XOR	R0, R0		// reset R0
-+	SUB	R6, R4		// remove base
-+	MOVD	R4, ret+24(FP)
-+	RET
-+notfound:
-+	XOR	R0, R0		// reset R0
-+	MOVD	$-1, R1
-+	MOVD	R1, ret+24(FP)
++TEXT runtime·memeqbodyclc(SB),NOSPLIT|NOFRAME,$0-0
++	CLC	$1, 0(R3), 0(R5)
 +	RET
 +
 +TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
@@ -23579,6 +34814,105 @@ index 0000000..861747e
 +	MOVW	R3, ret+0(FP)
 +	RET
 +
++TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
++	MOVD	s+0(FP), R3     // s => R3
++	MOVD	s_len+8(FP), R4 // s_len => R4
++	MOVBZ	c+24(FP), R5    // c => R5
++	MOVD	$ret+32(FP), R2 // &ret => R9
++	BR	runtime·indexbytebody(SB)
++
++TEXT strings·IndexByte(SB),NOSPLIT,$0-32
++	MOVD	s+0(FP), R3     // s => R3
++	MOVD	s_len+8(FP), R4 // s_len => R4
++	MOVBZ	c+16(FP), R5    // c => R5
++	MOVD	$ret+24(FP), R2 // &ret => R9
++	BR	runtime·indexbytebody(SB)
++
++// input:
++// R3: s
++// R4: s_len
++// R5: c -- byte sought
++// R2: &ret -- address to put index into
++TEXT runtime·indexbytebody(SB),NOSPLIT,$0
++	CMPBEQ	R4, $0, notfound
++	MOVD	R3, R6          // store base for later
++	ADD	R3, R4, R8      // the address after the end of the string
++	//if the length is small, use loop; otherwise, use vector or srst search
++	CMPBGE	R4, $16, large
++
++residual:
++	CMPBEQ	R3, R8, notfound
++	MOVBZ	0(R3), R7
++	LA	1(R3), R3
++	CMPBNE	R7, R5, residual
++
++found:
++	SUB	R6, R3
++	SUB	$1, R3
++	MOVD	R3, 0(R2)
++	RET
++
++notfound:
++	MOVD	$-1, 0(R2)
++	RET
++
++large:
++	MOVBZ	runtime·vectorfacility(SB), R1
++	CMPBEQ	R1, $1, vectorimpl      // vectorfacility = 1, vector supported
++
++srstimpl:                       // vectorfacility == 0, not support vector
++	MOVBZ	R5, R0          // c needs to be in R0, leave until last minute as currently R0 is expected to be 0
++srstloop:
++	WORD	$0xB25E0083     // srst %r8, %r3 (search the range [R3, R8))
++	BVS	srstloop        // interrupted - continue
++	BGT	notfoundr0
++foundr0:
++	XOR	R0, R0          // reset R0
++	SUB	R6, R8          // remove base
++	MOVD	R8, 0(R2)
++	RET
++notfoundr0:
++	XOR	R0, R0          // reset R0
++	MOVD	$-1, 0(R2)
++	RET
++
++vectorimpl:
++	//if the address is not 16byte aligned, use loop for the header
++	AND	$15, R3, R8
++	CMPBGT	R8, $0, notaligned
++
++aligned:
++	ADD	R6, R4, R8
++	AND	$-16, R8, R7
++	// replicate c across V17
++	VLVGB	$0, R5, V19
++	VREPB	$0, V19, V17
++
++vectorloop:
++	CMPBGE	R3, R7, residual
++	VL	0(R3), V16    // load string to be searched into V16
++	ADD	$16, R3
++	VFEEBS	V16, V17, V18 // search V17 in V16 and set conditional code accordingly
++	BVS	vectorloop
++
++	// when vector search found c in the string
++	VLGVB	$7, V18, R7   // load 7th element of V18 containing index into R7
++	SUB	$16, R3
++	SUB	R6, R3
++	ADD	R3, R7
++	MOVD	R7, 0(R2)
++	RET
++
++notaligned:
++	AND	$-16, R3, R8
++	ADD     $16, R8
++notalignedloop:
++	CMPBEQ	R3, R8, aligned
++	MOVBZ	0(R3), R7
++	LA	1(R3), R3
++	CMPBNE	R7, R5, notalignedloop
++	BR	found
++
 +TEXT runtime·return0(SB), NOSPLIT, $0
 +	MOVW	$0, R3
 +	RET
@@ -23630,106 +34964,39 @@ index 0000000..861747e
 +	SYNC
 +	RET
 +
-+TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
++TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40
 +	MOVD	s1_base+0(FP), R3
 +	MOVD	s1_len+8(FP), R4
 +	MOVD	s2_base+16(FP), R5
 +	MOVD	s2_len+24(FP), R6
-+	MOVD	R4, R8
-+	CMPBLE	R4, R6, s1min
-+	MOVD	R6, R8
-+s1min:
-+	CMPBEQ	R8, $0, cmplengths
-+	CMP	R8, $256
-+	BLE	tail
-+loop:
-+	CLC	$256, 0(R5), 0(R3)
-+	BGT	gt
-+	BLT	lt
-+	SUB	$256, R8
-+	CMP	R8, $256
-+	BGT	loop
-+tail:
-+	SUB	$1, R8
-+	EXRL	$runtime·cmpbody_clc(SB), R8
-+	BGT	gt
-+	BLT	lt
-+cmplengths:
-+	CMP	R4, R6
-+	BEQ	eq
-+	BLT	lt
-+	BGT	gt
-+gt:
-+	MOVD	$1, R7
-+	BR	quit
-+lt:
-+	MOVD	$-1, R7
-+	BR	quit
-+eq:
-+	MOVD	$0, R7
-+quit:
-+	MOVD	R7, ret+32(FP)
-+	RET
++	LA	ret+32(FP), R7
++	BR	runtime·cmpbody(SB)
 +
-+TEXT bytes·Compare(SB),NOSPLIT,$0-56
++TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
 +	MOVD	s1+0(FP), R3
 +	MOVD	s1+8(FP), R4
 +	MOVD	s2+24(FP), R5
 +	MOVD	s2+32(FP), R6
-+	MOVD	R4, R8
-+	CMPBLE	R4, R6, s1min
-+	MOVD	R6, R8
-+s1min:
-+	CMPBEQ	R8, $0, cmplengths
-+	CMP	R8, $256
-+	BLE	tail
-+loop:
-+	CLC	$256, 0(R5), 0(R3)
-+	BGT	gt
-+	BLT	lt
-+	SUB	$256, R8
-+	CMP	R8, $256
-+	BGT	loop
-+tail:
-+	SUB	$1, R8
-+	EXRL	$runtime·cmpbody_clc(SB), R8
-+	BGT	gt
-+	BLT	lt
-+cmplengths:
-+	CMP	R4, R6
-+	BEQ	eq
-+	BLT	lt
-+	BGT	gt
-+gt:
-+	MOVD	$1, R7
-+	BR	quit
-+lt:
-+	MOVD	$-1, R7
-+	BR	quit
-+eq:
-+	MOVD	$0, R7
-+quit:
-+	MOVD	R7, res+48(FP)
-+	RET
-+
-+TEXT runtime·cmpbody_clc(SB),NOSPLIT,$0-0
-+	CLC	$1, 0(R5), 0(R3)
-+	RET
++	LA	res+48(FP), R7
++	BR	runtime·cmpbody(SB)
 +
 +// input:
 +//   R3 = a
-+//   R5 = b
 +//   R4 = alen
++//   R5 = b
 +//   R6 = blen
 +//   R7 = address of output word (stores -1/0/1 here)
 +TEXT runtime·cmpbody(SB),NOSPLIT|NOFRAME,$0-0
++	CMPBEQ	R3, R5, cmplengths
 +	MOVD	R4, R8
-+	CMPBGE	R4, R6, 2(PC)
++	CMPBLE	R4, R6, amin
 +	MOVD	R6, R8
++amin:
++	CMPBEQ	R8, $0, cmplengths
 +	CMP	R8, $256
 +	BLE	tail
 +loop:
-+	CLC	$256, 0(R5), 0(R3)
++	CLC	$256, 0(R3), 0(R5)
 +	BGT	gt
 +	BLT	lt
 +	SUB	$256, R8
@@ -23737,22 +35004,25 @@ index 0000000..861747e
 +	BGT	loop
 +tail:
 +	SUB	$1, R8
-+	EXRL	$runtime·cmpbody_clc(SB), R8
++	EXRL	$runtime·cmpbodyclc(SB), R8
 +	BGT	gt
 +	BLT	lt
-+
++cmplengths:
 +	CMP	R4, R6
 +	BEQ	eq
 +	BLT	lt
-+	BGT	gt
 +gt:
-+	MOVD	$-1, R7
++	MOVD	$1, 0(R7)
 +	RET
 +lt:
-+	MOVD	$1, R7
++	MOVD	$-1, 0(R7)
 +	RET
 +eq:
-+	MOVD	$0, R7
++	MOVD	$0, 0(R7)
++	RET
++
++TEXT runtime·cmpbodyclc(SB),NOSPLIT|NOFRAME,$0-0
++	CLC	$1, 0(R3), 0(R5)
 +	RET
 +
 +// This is called from .init_array and follows the platform, not Go, ABI.
@@ -23762,13 +35032,7 @@ index 0000000..861747e
 +TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
 +	// Save R6-R15, F0, F2, F4 and F6 in the
 +	// register save area of the calling function
-+	// stmg %r6, %r15, 48(%r15)
-+	BYTE	$0xeb;
-+	BYTE	$0x6f;
-+	BYTE	$0xf0;
-+	BYTE	$0x30;
-+	BYTE	$0x00;
-+	BYTE	$0x24;
++	STMG	R6, R15, 48(R15)
 +	FMOVD	F0, 128(R15)
 +	FMOVD	F2, 136(R15)
 +	FMOVD	F4, 144(R15)
@@ -23781,13 +35045,7 @@ index 0000000..861747e
 +	MOVD	R2, runtime·lastmoduledatap(SB)
 +
 +	// Restore R6-R15, F0, F2, F4 and F6
-+	// lmg %r6, %r15, 48(%r15)
-+	BYTE	$0xeb;
-+	BYTE	$0x6f;
-+	BYTE	$0xf0;
-+	BYTE	$0x30;
-+	BYTE	$0x00;
-+	BYTE	$0x04;
++	LMG	48(R15), R6, R15
 +	FMOVD	F0, 128(R15)
 +	FMOVD	F2, 136(R15)
 +	FMOVD	F4, 144(R15)
@@ -23800,10 +35058,10 @@ index 0000000..861747e
 +	RET
 diff --git a/src/runtime/cgo/asm_s390x.s b/src/runtime/cgo/asm_s390x.s
 new file mode 100644
-index 0000000..64b2ab4
+index 0000000..dcb1e6b
 --- /dev/null
 +++ b/src/runtime/cgo/asm_s390x.s
-@@ -0,0 +1,56 @@
+@@ -0,0 +1,44 @@
 +// Copyright 2016 The Go Authors.  All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -23820,13 +35078,7 @@ index 0000000..64b2ab4
 +
 +	// Save R6-R15, F0, F2, F4 and F6 in the
 +	// register save area of the calling function
-+	// stmg %r6, %r15, 48(%r15)
-+	BYTE	$0xeb;
-+	BYTE	$0x6f;
-+	BYTE	$0xf0;
-+	BYTE	$0x30;
-+	BYTE	$0x00;
-+	BYTE	$0x24;
++	STMG	R6, R15, 48(R15)
 +	FMOVD	F0, 128(R15)
 +	FMOVD	F2, 136(R15)
 +	FMOVD	F4, 144(R15)
@@ -23846,13 +35098,7 @@ index 0000000..64b2ab4
 +	ADD	$24, R15
 +
 +	// Restore R6-R15, F0, F2, F4 and F6
-+	// lmg %r6, %r15, 48(%r15)
-+	BYTE	$0xeb;
-+	BYTE	$0x6f;
-+	BYTE	$0xf0;
-+	BYTE	$0x30;
-+	BYTE	$0x00;
-+	BYTE	$0x04;
++	LMG	48(R15), R6, R15
 +	FMOVD	F0, 128(R15)
 +	FMOVD	F2, 136(R15)
 +	FMOVD	F4, 144(R15)
@@ -23984,7 +35230,7 @@ index 0000000..dc242eb
 +.section .note.GNU-stack,"",%progbits
 +#endif
 diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
-index 66115fd..634b6e7 100644
+index 66115fd..7d9910c 100644
 --- a/src/runtime/cgocall.go
 +++ b/src/runtime/cgocall.go
 @@ -239,8 +239,8 @@ func cgocallbackg1() {
@@ -24007,6 +35253,79 @@ index 66115fd..634b6e7 100644
  		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + sys.MinFrameSize))
  	case "arm64":
  		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 16))
+@@ -463,6 +463,9 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
+ 		if !top {
+ 			panic(errorString(msg))
+ 		}
++		if st.elem.kind&kindNoPointers != 0 {
++			return
++		}
+ 		for i := 0; i < s.cap; i++ {
+ 			cgoCheckArg(st.elem, p, true, false, msg)
+ 			p = add(p, st.elem.size)
+diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
+index d7b367f..7685582 100644
+--- a/src/runtime/crash_cgo_test.go
++++ b/src/runtime/crash_cgo_test.go
+@@ -7,10 +7,12 @@
+ package runtime_test
+ 
+ import (
++	"internal/testenv"
+ 	"os/exec"
+ 	"runtime"
+ 	"strings"
+ 	"testing"
++	"time"
+ )
+ 
+ func TestCgoCrashHandler(t *testing.T) {
+@@ -147,3 +149,32 @@ func TestEnsureDropM(t *testing.T) {
+ 		t.Errorf("expected %q, got %v", want, got)
+ 	}
+ }
++
++// Test for issue 14387.
++// Test that the program that doesn't need any cgo pointer checking
++// takes about the same amount of time with it as without it.
++func TestCgoCheckBytes(t *testing.T) {
++	// Make sure we don't count the build time as part of the run time.
++	testenv.MustHaveGoBuild(t)
++	exe, err := buildTestProg(t, "testprogcgo")
++	if err != nil {
++		t.Fatal(err)
++	}
++
++	cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))
++
++	start := time.Now()
++	cmd.Run()
++	d1 := time.Since(start)
++
++	cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
++	cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0")
++
++	start = time.Now()
++	cmd.Run()
++	d2 := time.Since(start)
++
++	if d2*10 < d1 {
++		t.Errorf("cgo check too slow: got %v, expected at most %v", d1, d2*10)
++	}
++}
+diff --git a/src/runtime/debug/stack_test.go b/src/runtime/debug/stack_test.go
+index f544372..9376e82 100644
+--- a/src/runtime/debug/stack_test.go
++++ b/src/runtime/debug/stack_test.go
+@@ -59,7 +59,7 @@ func TestStack(t *testing.T) {
+ }
+ 
+ func check(t *testing.T, line, has string) {
+-	if strings.Index(line, has) < 0 {
++	if !strings.Contains(line, has) {
+ 		t.Errorf("expected %q in %q", has, line)
+ 	}
+ }
 diff --git a/src/runtime/defs_linux_s390x.go b/src/runtime/defs_linux_s390x.go
 new file mode 100644
 index 0000000..893a31c
@@ -25276,10 +36595,10 @@ index 0000000..0b09332
 +}
 diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
 new file mode 100644
-index 0000000..9431fc2
+index 0000000..a4a4693
 --- /dev/null
 +++ b/src/runtime/sys_linux_s390x.s
-@@ -0,0 +1,437 @@
+@@ -0,0 +1,440 @@
 +// Copyright 2016 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -25528,17 +36847,17 @@ index 0000000..9431fc2
 +	BL	R11
 +	RET
 +
++// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
 +TEXT runtime·mmap(SB),NOSPLIT,$48-40
 +	MOVD	addr+0(FP), R2
 +	MOVD	n+8(FP), R3
 +	MOVW	prot+16(FP), R4
 +	MOVW	flags+20(FP), R5
 +	MOVW	fd+24(FP), R6
-+	MOVW	off+28(FP), R7 
++	MOVWZ	off+28(FP), R7
 +
 +	// s390x uses old_mmap, so the arguments need to be placed into
 +	// a struct and a pointer to the struct passed to mmap.
-+	// TODO Offset should NOT be sign extended (it is a uint32).
 +	MOVD	R2, addr-48(SP)
 +	MOVD	R3, n-40(SP)
 +	MOVD	R4, prot-32(SP)
@@ -25549,6 +36868,9 @@ index 0000000..9431fc2
 +	MOVD	$addr-48(SP), R2
 +	MOVW	$SYS_mmap, R1
 +	SYSCALL
++	MOVD	$-4095, R3
++	CMPUBLT	R2, R3, 2(PC)
++	NEG	R2
 +	MOVD	R2, ret+32(FP)
 +	RET
 +
@@ -25771,6 +37093,42 @@ index 0000000..106d7ea
 +	print("runtime: pc=", hex(buf.pc), " ", hex(inst), "\n")
 +	throw("runtime: misuse of rewindmorestack")
 +}
+diff --git a/src/runtime/testdata/testprogcgo/cgo.go b/src/runtime/testdata/testprogcgo/cgo.go
+index cf1af82..5d2550d 100644
+--- a/src/runtime/testdata/testprogcgo/cgo.go
++++ b/src/runtime/testdata/testprogcgo/cgo.go
+@@ -6,17 +6,20 @@ package main
+ 
+ /*
+ void foo1(void) {}
++void foo2(void* p) {}
+ */
+ import "C"
+ import (
+ 	"fmt"
+ 	"runtime"
+ 	"time"
++	"unsafe"
+ )
+ 
+ func init() {
+ 	register("CgoSignalDeadlock", CgoSignalDeadlock)
+ 	register("CgoTraceback", CgoTraceback)
++	register("CgoCheckBytes", CgoCheckBytes)
+ }
+ 
+ func CgoSignalDeadlock() {
+@@ -78,3 +81,10 @@ func CgoTraceback() {
+ 	runtime.Stack(buf, true)
+ 	fmt.Printf("OK\n")
+ }
++
++func CgoCheckBytes() {
++	b := make([]byte, 1e6)
++	for i := 0; i < 1e3; i++ {
++		C.foo2(unsafe.Pointer(&b[0]))
++	}
++}
 diff --git a/src/runtime/tls_s390x.s b/src/runtime/tls_s390x.s
 new file mode 100644
 index 0000000..03bfc50
@@ -25841,6 +37199,19 @@ index d3d6c70..602fd67 100644
  
  package runtime
  
+diff --git a/src/sort/sort.go b/src/sort/sort.go
+index ac8f4a6..5eb45c6 100644
+--- a/src/sort/sort.go
++++ b/src/sort/sort.go
+@@ -335,7 +335,7 @@ func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
+ //    unstable or rely on enough different elements in each step to encode the
+ //    performed block rearrangements. See also "In-Place Merging Algorithms",
+ //    Denham Coates-Evely, Department of Computer Science, Kings College,
+-//    January 2004 and the reverences in there.
++//    January 2004 and the references in there.
+ //  - Often "optimal" algorithms are optimal in the number of assignments
+ //    but Interface has only Swap as operation.
+ 
 diff --git a/src/sync/atomic/asm_s390x.s b/src/sync/atomic/asm_s390x.s
 new file mode 100644
 index 0000000..a96cce3
@@ -26218,12 +37589,39 @@ index 85fab4f..1d40092 100755
  nacl_386)
  	mkerrors=""
  	mksyscall="./mksyscall.pl -l32 -nacl"
+diff --git a/src/syscall/mksyscall.pl b/src/syscall/mksyscall.pl
+index 96437fe..6ee7c3c 100755
+--- a/src/syscall/mksyscall.pl
++++ b/src/syscall/mksyscall.pl
+@@ -100,7 +100,7 @@ while(<>) {
+ 	# Line must be of the form
+ 	#	func Open(path string, mode int, perm int) (fd int, errno error)
+ 	# Split into name, in params, out params.
+-	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) {
++	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)_?SYS_[A-Z0-9_]+))?$/) {
+ 		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+ 		$errors = 1;
+ 		next;
+diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
+index 2875067..b5e33bf 100644
+--- a/src/syscall/syscall_linux.go
++++ b/src/syscall/syscall_linux.go
+@@ -301,7 +301,8 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ 	}
+ 	sa.raw.Family = AF_UNIX
+ 	for i := 0; i < n; i++ {
+-		sa.raw.Path[i] = int8(name[i])
++		bp := (*byte)(unsafe.Pointer(&sa.raw.Path[i]))
++		*bp = name[i]
+ 	}
+ 	// length is family (uint16), name, NUL.
+ 	sl := _Socklen(2)
 diff --git a/src/syscall/syscall_linux_s390x.go b/src/syscall/syscall_linux_s390x.go
 new file mode 100644
-index 0000000..20a1a45
+index 0000000..4fc9c3f
 --- /dev/null
 +++ b/src/syscall/syscall_linux_s390x.go
-@@ -0,0 +1,296 @@
+@@ -0,0 +1,299 @@
 +// Copyright 2016 The Go Authors. All rights reserved.
 +// Use of this source code is governed by a BSD-style
 +// license that can be found in the LICENSE file.
@@ -26232,7 +37630,10 @@ index 0000000..20a1a45
 +
 +import "unsafe"
 +
-+const _SYS_dup = SYS_DUP2
++const (
++       _SYS_dup = SYS_DUP2
++       _SYS_getdents = SYS_GETDENTS64
++)
 +
 +//sys	Dup2(oldfd int, newfd int) (err error)
 +//sys	Fchown(fd int, uid int, gid int) (err error)
@@ -26562,10 +37963,10 @@ index cff4069..6d197d8 100644
  // Misc
 diff --git a/src/syscall/zerrors_linux_s390x.go b/src/syscall/zerrors_linux_s390x.go
 new file mode 100644
-index 0000000..4e25255
+index 0000000..547419f
 --- /dev/null
 +++ b/src/syscall/zerrors_linux_s390x.go
-@@ -0,0 +1,1869 @@
+@@ -0,0 +1,1893 @@
 +// mkerrors.sh -m64
 +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
 +
@@ -26600,7 +38001,7 @@ index 0000000..4e25255
 +	AF_KEY                           = 0xf
 +	AF_LLC                           = 0x1a
 +	AF_LOCAL                         = 0x1
-+	AF_MAX                           = 0x28
++	AF_MAX                           = 0x29
 +	AF_NETBEUI                       = 0xd
 +	AF_NETLINK                       = 0x10
 +	AF_NETROM                        = 0x6
@@ -26617,6 +38018,7 @@ index 0000000..4e25255
 +	AF_TIPC                          = 0x1e
 +	AF_UNIX                          = 0x1
 +	AF_UNSPEC                        = 0x0
++	AF_VSOCK                         = 0x28
 +	AF_WANPIPE                       = 0x19
 +	AF_X25                           = 0x9
 +	ARPHRD_ADAPT                     = 0x108
@@ -26833,12 +38235,10 @@ index 0000000..4e25255
 +	EPOLL_CTL_ADD                    = 0x1
 +	EPOLL_CTL_DEL                    = 0x2
 +	EPOLL_CTL_MOD                    = 0x3
-+	EPOLL_NONBLOCK                   = 0x800
 +	ETH_P_1588                       = 0x88f7
 +	ETH_P_8021AD                     = 0x88a8
 +	ETH_P_8021AH                     = 0x88e7
 +	ETH_P_8021Q                      = 0x8100
-+	ETH_P_80221                      = 0x8917
 +	ETH_P_802_2                      = 0x4
 +	ETH_P_802_3                      = 0x1
 +	ETH_P_802_3_MIN                  = 0x600
@@ -26958,15 +38358,13 @@ index 0000000..4e25255
 +	IFA_F_DADFAILED                  = 0x8
 +	IFA_F_DEPRECATED                 = 0x20
 +	IFA_F_HOMEADDRESS                = 0x10
-+	IFA_F_MANAGETEMPADDR             = 0x100
 +	IFA_F_NODAD                      = 0x2
-+	IFA_F_NOPREFIXROUTE              = 0x200
 +	IFA_F_OPTIMISTIC                 = 0x4
 +	IFA_F_PERMANENT                  = 0x80
 +	IFA_F_SECONDARY                  = 0x1
 +	IFA_F_TEMPORARY                  = 0x1
 +	IFA_F_TENTATIVE                  = 0x40
-+	IFA_MAX                          = 0x8
++	IFA_MAX                          = 0x7
 +	IFF_802_1Q_VLAN                  = 0x1
 +	IFF_ALLMULTI                     = 0x200
 +	IFF_ATTACH_QUEUE                 = 0x200
@@ -26994,10 +38392,12 @@ index 0000000..4e25255
 +	IFF_MULTICAST                    = 0x1000
 +	IFF_MULTI_QUEUE                  = 0x100
 +	IFF_NOARP                        = 0x80
++	IFF_NOFILTER                     = 0x1000
 +	IFF_NOTRAILERS                   = 0x20
 +	IFF_NO_PI                        = 0x1000
 +	IFF_ONE_QUEUE                    = 0x2000
 +	IFF_OVS_DATAPATH                 = 0x8000
++	IFF_PERSIST                      = 0x800
 +	IFF_POINTOPOINT                  = 0x10
 +	IFF_PORTSEL                      = 0x2000
 +	IFF_PROMISC                      = 0x100
@@ -27063,6 +38463,7 @@ index 0000000..4e25255
 +	IN_Q_OVERFLOW                    = 0x4000
 +	IN_UNMOUNT                       = 0x2000
 +	IPPROTO_AH                       = 0x33
++	IPPROTO_BEETPH                   = 0x5e
 +	IPPROTO_COMP                     = 0x6c
 +	IPPROTO_DCCP                     = 0x21
 +	IPPROTO_DSTOPTS                  = 0x3c
@@ -27079,6 +38480,7 @@ index 0000000..4e25255
 +	IPPROTO_IP                       = 0x0
 +	IPPROTO_IPIP                     = 0x4
 +	IPPROTO_IPV6                     = 0x29
++	IPPROTO_MH                       = 0x87
 +	IPPROTO_MTP                      = 0x5c
 +	IPPROTO_NONE                     = 0x3b
 +	IPPROTO_PIM                      = 0x67
@@ -27231,8 +38633,9 @@ index 0000000..4e25255
 +	MAP_FILE                         = 0x0
 +	MAP_FIXED                        = 0x10
 +	MAP_GROWSDOWN                    = 0x100
-+	MAP_GROWSUP                      = 0x200
 +	MAP_HUGETLB                      = 0x40000
++	MAP_HUGE_MASK                    = 0x3f
++	MAP_HUGE_SHIFT                   = 0x1a
 +	MAP_LOCKED                       = 0x2000
 +	MAP_NONBLOCK                     = 0x10000
 +	MAP_NORESERVE                    = 0x4000
@@ -27380,6 +38783,7 @@ index 0000000..4e25255
 +	O_RDWR                           = 0x2
 +	O_RSYNC                          = 0x101000
 +	O_SYNC                           = 0x101000
++	O_TMPFILE                        = 0x410000
 +	O_TRUNC                          = 0x200
 +	O_WRONLY                         = 0x1
 +	PACKET_ADD_MEMBERSHIP            = 0x1
@@ -27467,7 +38871,6 @@ index 0000000..4e25255
 +	PR_GET_PDEATHSIG                 = 0x2
 +	PR_GET_SECCOMP                   = 0x15
 +	PR_GET_SECUREBITS                = 0x1b
-+	PR_GET_THP_DISABLE               = 0x2a
 +	PR_GET_TID_ADDRESS               = 0x28
 +	PR_GET_TIMERSLACK                = 0x1e
 +	PR_GET_TIMING                    = 0xd
@@ -27507,7 +38910,6 @@ index 0000000..4e25255
 +	PR_SET_PTRACER_ANY               = -0x1
 +	PR_SET_SECCOMP                   = 0x16
 +	PR_SET_SECUREBITS                = 0x1c
-+	PR_SET_THP_DISABLE               = 0x29
 +	PR_SET_TIMERSLACK                = 0x1d
 +	PR_SET_TIMING                    = 0xe
 +	PR_SET_TSC                       = 0x1a
@@ -27537,6 +38939,7 @@ index 0000000..4e25255
 +	PTRACE_GETREGS                   = 0xc
 +	PTRACE_GETREGSET                 = 0x4204
 +	PTRACE_GETSIGINFO                = 0x4202
++	PTRACE_GETSIGMASK                = 0x420a
 +	PTRACE_GET_LAST_BREAK            = 0x5006
 +	PTRACE_INTERRUPT                 = 0x4207
 +	PTRACE_KILL                      = 0x8
@@ -27574,8 +38977,10 @@ index 0000000..4e25255
 +	PTRACE_SETREGS                   = 0xd
 +	PTRACE_SETREGSET                 = 0x4205
 +	PTRACE_SETSIGINFO                = 0x4203
++	PTRACE_SETSIGMASK                = 0x420b
 +	PTRACE_SINGLESTEP                = 0x9
 +	PTRACE_SYSCALL                   = 0x18
++	PTRACE_TE_ABORT_RAND             = 0x5011
 +	PTRACE_TRACEME                   = 0x0
 +	PT_ACR0                          = 0x90
 +	PT_ACR1                          = 0x94
@@ -27654,7 +39059,7 @@ index 0000000..4e25255
 +	RTAX_INITCWND                    = 0xb
 +	RTAX_INITRWND                    = 0xe
 +	RTAX_LOCK                        = 0x1
-+	RTAX_MAX                         = 0x17
++	RTAX_MAX                         = 0xf
 +	RTAX_MTU                         = 0x2
 +	RTAX_QUICKACK                    = 0xf
 +	RTAX_REORDERING                  = 0x9
@@ -27875,7 +39280,6 @@ index 0000000..4e25255
 +	SO_ACCEPTCONN                    = 0x1e
 +	SO_ATTACH_FILTER                 = 0x1a
 +	SO_BINDTODEVICE                  = 0x19
-+	SO_BPF_EXTENSIONS                = 0x30
 +	SO_BROADCAST                     = 0x6
 +	SO_BSDCOMPAT                     = 0xe
 +	SO_BUSY_POLL                     = 0x2e
@@ -27952,8 +39356,15 @@ index 0000000..4e25255
 +	TCIOFLUSH                        = 0x2
 +	TCOFLUSH                         = 0x1
 +	TCP_CONGESTION                   = 0xd
++	TCP_COOKIE_IN_ALWAYS             = 0x1
++	TCP_COOKIE_MAX                   = 0x10
++	TCP_COOKIE_MIN                   = 0x8
++	TCP_COOKIE_OUT_NEVER             = 0x2
++	TCP_COOKIE_PAIR_SIZE             = 0x20
++	TCP_COOKIE_TRANSACTIONS          = 0xf
 +	TCP_CORK                         = 0x3
 +	TCP_DEFER_ACCEPT                 = 0x9
++	TCP_FASTOPEN                     = 0x17
 +	TCP_INFO                         = 0xb
 +	TCP_KEEPCNT                      = 0x6
 +	TCP_KEEPIDLE                     = 0x4
@@ -27965,9 +39376,21 @@ index 0000000..4e25255
 +	TCP_MD5SIG                       = 0xe
 +	TCP_MD5SIG_MAXKEYLEN             = 0x50
 +	TCP_MSS                          = 0x200
++	TCP_MSS_DEFAULT                  = 0x218
++	TCP_MSS_DESIRED                  = 0x4c4
 +	TCP_NODELAY                      = 0x1
++	TCP_QUEUE_SEQ                    = 0x15
 +	TCP_QUICKACK                     = 0xc
++	TCP_REPAIR                       = 0x13
++	TCP_REPAIR_OPTIONS               = 0x16
++	TCP_REPAIR_QUEUE                 = 0x14
 +	TCP_SYNCNT                       = 0x7
++	TCP_S_DATA_IN                    = 0x4
++	TCP_S_DATA_OUT                   = 0x8
++	TCP_THIN_DUPACK                  = 0x11
++	TCP_THIN_LINEAR_TIMEOUTS         = 0x10
++	TCP_TIMESTAMP                    = 0x18
++	TCP_USER_TIMEOUT                 = 0x12
 +	TCP_WINDOW_CLAMP                 = 0xa
 +	TCSAFLUSH                        = 0x2
 +	TIOCCBRK                         = 0x5428
@@ -28042,12 +39465,14 @@ index 0000000..4e25255
 +	TUNATTACHFILTER                  = 0x401054d5
 +	TUNDETACHFILTER                  = 0x401054d6
 +	TUNGETFEATURES                   = 0x800454cf
++	TUNGETFILTER                     = 0x801054db
 +	TUNGETIFF                        = 0x800454d2
 +	TUNGETSNDBUF                     = 0x800454d3
 +	TUNGETVNETHDRSZ                  = 0x800454d7
 +	TUNSETDEBUG                      = 0x400454c9
 +	TUNSETGROUP                      = 0x400454ce
 +	TUNSETIFF                        = 0x400454ca
++	TUNSETIFINDEX                    = 0x400454da
 +	TUNSETLINK                       = 0x400454cd
 +	TUNSETNOCSUM                     = 0x400454c8
 +	TUNSETOFFLOAD                    = 0x400454d0
@@ -28437,7 +39862,7 @@ index 0000000..4e25255
 +}
 diff --git a/src/syscall/zsyscall_linux_s390x.go b/src/syscall/zsyscall_linux_s390x.go
 new file mode 100644
-index 0000000..d103c57
+index 0000000..e5b941c
 --- /dev/null
 +++ b/src/syscall/zsyscall_linux_s390x.go
 @@ -0,0 +1,1578 @@
@@ -28948,7 +40373,7 @@ index 0000000..d103c57
 +	} else {
 +		_p0 = unsafe.Pointer(&_zero)
 +	}
-+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
++	r0, _, e1 := Syscall(_SYS_getdents, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 +	n = int(r0)
 +	if e1 != 0 {
 +		err = errnoErr(e1)
@@ -30320,10 +41745,10 @@ index 0000000..90e6b2f
 +)
 diff --git a/src/syscall/ztypes_linux_s390x.go b/src/syscall/ztypes_linux_s390x.go
 new file mode 100644
-index 0000000..87b86e2
+index 0000000..e994c58
 --- /dev/null
 +++ b/src/syscall/ztypes_linux_s390x.go
-@@ -0,0 +1,623 @@
+@@ -0,0 +1,621 @@
 +// Created by cgo -godefs - DO NOT EDIT
 +// cgo -godefs types_linux.go
 +
@@ -30425,21 +41850,21 @@ index 0000000..87b86e2
 +type _Gid_t uint32
 +
 +type Stat_t struct {
-+	Dev       uint64
-+	Ino       uint64
-+	Nlink     uint64
-+	Mode      uint32
-+	Uid       uint32
-+	Gid       uint32
-+	Pad0      int32
-+	Rdev      uint64
-+	Size      int64
-+	Atim      Timespec
-+	Mtim      Timespec
-+	Ctim      Timespec
-+	Blksize   int64
-+	Blocks    int64
-+	X__unused [3]int64
++	Dev               uint64
++	Ino               uint64
++	Nlink             uint64
++	Mode              uint32
++	Uid               uint32
++	Gid               uint32
++	Pad0              int32
++	Rdev              uint64
++	Size              int64
++	Atim              Timespec
++	Mtim              Timespec
++	Ctim              Timespec
++	Blksize           int64
++	Blocks            int64
++	X__glibc_reserved [3]int64
 +}
 +
 +type Statfs_t struct {
@@ -30498,7 +41923,7 @@ index 0000000..87b86e2
 +
 +type RawSockaddrUnix struct {
 +	Family uint16
-+	Path   [108]int8
++	Path   [108]uint8
 +}
 +
 +type RawSockaddrLinklayer struct {
@@ -30569,10 +41994,9 @@ index 0000000..87b86e2
 +}
 +
 +type Cmsghdr struct {
-+	Len          uint64
-+	Level        int32
-+	Type         int32
-+	X__cmsg_data [0]uint8
++	Len   uint64
++	Level int32
++	Type  int32
 +}
 +
 +type Inet4Pktinfo struct {
@@ -30836,7 +42260,6 @@ index 0000000..87b86e2
 +	Mask   uint32
 +	Cookie uint32
 +	Len    uint32
-+	Name   [0]uint8
 +}
 +
 +const SizeofInotifyEvent = 0x10
@@ -30947,6 +42370,108 @@ index 0000000..87b86e2
 +	TCSETS = 0x5402
 +	XCASE  = 0x4
 +)
+diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go
+index 0155800..dd87850 100644
+--- a/src/text/scanner/scanner.go
++++ b/src/text/scanner/scanner.go
+@@ -333,7 +333,7 @@ func (s *Scanner) error(msg string) {
+ 	if !pos.IsValid() {
+ 		pos = s.Pos()
+ 	}
+-	fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
++	fmt.Fprintf(os.Stderr, "text/scanner: %s: %s\n", pos, msg)
+ }
+ 
+ func (s *Scanner) isIdentRune(ch rune, i int) bool {
+diff --git a/src/text/template/exec.go b/src/text/template/exec.go
+index efe1817..5ea45a4 100644
+--- a/src/text/template/exec.go
++++ b/src/text/template/exec.go
+@@ -446,7 +446,7 @@ func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
+ 	switch {
+ 	case constant.IsComplex:
+ 		return reflect.ValueOf(constant.Complex128) // incontrovertible.
+-	case constant.IsFloat && !isHexConstant(constant.Text) && strings.IndexAny(constant.Text, ".eE") >= 0:
++	case constant.IsFloat && !isHexConstant(constant.Text) && strings.ContainsAny(constant.Text, ".eE"):
+ 		return reflect.ValueOf(constant.Float64)
+ 	case constant.IsInt:
+ 		n := int(constant.Int64)
+diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
+index 49e9e74..58b8ea3 100644
+--- a/src/text/template/funcs.go
++++ b/src/text/template/funcs.go
+@@ -515,7 +515,7 @@ func HTMLEscape(w io.Writer, b []byte) {
+ // HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+ func HTMLEscapeString(s string) string {
+ 	// Avoid allocation if we can.
+-	if strings.IndexAny(s, `'"&<>`) < 0 {
++	if !strings.ContainsAny(s, `'"&<>`) {
+ 		return s
+ 	}
+ 	var b bytes.Buffer
+diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
+index ea93e05..079c0ea 100644
+--- a/src/text/template/parse/lex.go
++++ b/src/text/template/parse/lex.go
+@@ -155,7 +155,7 @@ func (l *lexer) ignore() {
+ 
+ // accept consumes the next rune if it's from the valid set.
+ func (l *lexer) accept(valid string) bool {
+-	if strings.IndexRune(valid, l.next()) >= 0 {
++	if strings.ContainsRune(valid, l.next()) {
+ 		return true
+ 	}
+ 	l.backup()
+@@ -164,7 +164,7 @@ func (l *lexer) accept(valid string) bool {
+ 
+ // acceptRun consumes a run of runes from the valid set.
+ func (l *lexer) acceptRun(valid string) {
+-	for strings.IndexRune(valid, l.next()) >= 0 {
++	for strings.ContainsRune(valid, l.next()) {
+ 	}
+ 	l.backup()
+ }
+diff --git a/src/time/format_test.go b/src/time/format_test.go
+index af950a7..8c47dbc 100644
+--- a/src/time/format_test.go
++++ b/src/time/format_test.go
+@@ -447,7 +447,7 @@ func TestParseErrors(t *testing.T) {
+ 		_, err := Parse(test.format, test.value)
+ 		if err == nil {
+ 			t.Errorf("expected error for %q %q", test.format, test.value)
+-		} else if strings.Index(err.Error(), test.expect) < 0 {
++		} else if !strings.Contains(err.Error(), test.expect) {
+ 			t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
+ 		}
+ 	}
+diff --git a/test/escape_iface.go b/test/escape_iface.go
+index 2b1144a..9149fa1 100644
+--- a/test/escape_iface.go
++++ b/test/escape_iface.go
+@@ -225,3 +225,23 @@ func dotTypeEscape() *T2 { // #11931
+ 		T1: *(x.(*T1)), // ERROR "&T2 literal escapes to heap"
+ 	}
+ }
++
++func dotTypeEscape2() { // #13805
++	{
++		i := 0
++		var v int
++		var x interface{} = i // ERROR "i does not escape"
++		*(&v) = x.(int) // ERROR "&v does not escape"
++	}
++	{
++		i := 0
++		var x interface{} = i // ERROR "i does not escape"
++		sink = x.(int)        // ERROR "x.\(int\) escapes to heap"
++
++	}
++	{
++		i := 0 // ERROR "moved to heap: i"
++		var x interface{} = &i // ERROR "&i escapes to heap"
++		sink = x.(*int)        // ERROR "x.\(\*int\) escapes to heap"
++	}
++}
 diff --git a/test/fixedbugs/issue11656.go b/test/fixedbugs/issue11656.go
 index 565e796..08c143e 100644
 --- a/test/fixedbugs/issue11656.go
@@ -30973,6 +42498,19 @@ index 62dfb72..a008e3e 100644
  		panic("init1")
  	}
  }
+diff --git a/test/linkx_run.go b/test/linkx_run.go
+index a6c7c67..440271a 100644
+--- a/test/linkx_run.go
++++ b/test/linkx_run.go
+@@ -18,7 +18,7 @@ import (
+ )
+ 
+ func main() {
+-	test(" ") // old deprecated syntax
++	// test(" ") // old deprecated & removed syntax
+ 	test("=") // new syntax
+ }
+ 
 diff --git a/test/nilptr3.go b/test/nilptr3.go
 index 6c8aab3..7d579fd 100644
 --- a/test/nilptr3.go
@@ -31001,6 +42539,3 @@ index 3c4ae10..189a320 100644
  		default:
  			fmt.Fprintf(&buf, "#define REGISTER AX\n")
  		}
--- 
-2.5.0
-

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git



More information about the pkg-golang-commits mailing list